📄 jythonplugin.java
字号:
package org.python.pydev.jython;
import java.io.File;
import java.io.FileFilter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.python.core.PyException;
import org.python.core.PyJavaClass;
import org.python.core.PyObject;
import org.python.core.PySystemState;
import org.python.pydev.core.REF;
import org.python.pydev.core.Tuple;
import org.python.pydev.core.bundle.BundleInfo;
import org.python.pydev.core.bundle.IBundleInfo;
import org.python.pydev.core.docutils.StringUtils;
import org.python.pydev.core.log.Log;
import org.python.pydev.jython.ui.JyScriptingPreferencesPage;
import org.python.util.PythonInterpreter;
/**
* The main plugin class to be used in the desktop.
*/
public class JythonPlugin extends AbstractUIPlugin {
private static final boolean DEBUG = false;
public static boolean DEBUG_RELOAD = true;
/**
* While in tests, errors are thrown even if we don't have a shared instance for JythonPlugin
*/
public static boolean IN_TESTS = false;
private static String LOAD_FILE_SCRIPT = "" +
"print '---> reloading', r'%s'\n" +
"import sys \n" + //sys will always be on the namespace (so that we can set sys.path)
"f = open(r'%s') \n" +
"try: \n" +
" toExec = f.read() \n" +
"finally: \n" +
" f.close() \n" +
"%s \n" + //space to put the needed folders on sys.path
"";
public static synchronized void setDebugReload(boolean b){
if(b != DEBUG_RELOAD){
if(b == false){
LOAD_FILE_SCRIPT = "#"+LOAD_FILE_SCRIPT;
//System.out.println(">>"+LOAD_FILE_SCRIPT+"<<");
}else{
LOAD_FILE_SCRIPT = LOAD_FILE_SCRIPT.substring(1);
//System.out.println(">>"+LOAD_FILE_SCRIPT+"<<");
}
DEBUG_RELOAD = b;
}
}
// ----------------- SINGLETON THINGS -----------------------------
public static IBundleInfo info;
public static IBundleInfo getBundleInfo(){
if(JythonPlugin.info == null){
JythonPlugin.info = new BundleInfo(JythonPlugin.getDefault().getBundle());
}
return JythonPlugin.info;
}
public static void setBundleInfo(IBundleInfo b){
JythonPlugin.info = b;
}
// ----------------- END BUNDLE INFO THINGS --------------------------
//The shared instance.
private static JythonPlugin plugin;
/**
* The constructor.
*/
public JythonPlugin() {
plugin = this;
}
// ------------------------------------------
/**
* Classloader that knows about all the bundles...
*/
public static class AllBundleClassLoader extends ClassLoader {
private Bundle[] bundles;
public AllBundleClassLoader(Bundle[] bundles, ClassLoader parent) {
super(parent);
this.bundles = bundles;
setPackageNames(bundles);
}
@SuppressWarnings("unchecked")
public Class loadClass(String className) throws ClassNotFoundException {
try {
return super.loadClass(className);
} catch (ClassNotFoundException e) {
// Look for the class from the bundles.
for (int i = 0; i < bundles.length; ++i) {
try {
if(bundles[i].getState() == Bundle.ACTIVE){
return bundles[i].loadClass(className);
}
} catch (Throwable e2) {
}
}
// Didn't find the class anywhere, rethrow e.
throw e;
}
}
/**
* The package names the bundles provide
*/
private String[] packageNames;
/**
* Set the package names available given the bundles that we can access
*/
private void setPackageNames(Bundle[] bundles) {
List<String> names = new ArrayList<String>();
for (int i = 0; i < bundles.length; ++i) {
String packages = (String) bundles[i].getHeaders().get("Provide-Package");
if (packages != null) {
String[] pnames = packages.split(",");
for (int j = 0; j < pnames.length; ++j) {
names.add(pnames[j].trim());
}
}
packages = (String) bundles[i].getHeaders().get("Export-Package");
if (packages != null) {
String[] pnames = packages.split(",");
for (int j = 0; j < pnames.length; ++j) {
names.add(pnames[j].trim());
}
}
}
packageNames = (String[]) names.toArray(new String[names.size()]);
}
/**
* @return the package names available for the passed bundles
*/
public String[] getPackageNames() {
return packageNames;
}
}
//------------------------------------------
AllBundleClassLoader allBundleClassLoader;
/**
* This method is called upon plug-in activation
*/
public void start(BundleContext context) throws Exception {
super.start(context);
//initialize the Jython runtime
Properties prop2 = new Properties();
prop2.put("python.home", REF.getFileAbsolutePath(getPluginRootDir()));
prop2.put("python.path", REF.getFileAbsolutePath(getJySrcDirFile()));
prop2.put("python.security.respectJavaAccessibility", "false"); //don't respect java accessibility, so that we can access protected members on subclasses
try {
allBundleClassLoader = new AllBundleClassLoader(context.getBundles(), this.getClass().getClassLoader());
PySystemState.initialize(System.getProperties(), prop2, new String[0], allBundleClassLoader);
String[] packageNames = getDefault().allBundleClassLoader.getPackageNames();
for (int i = 0; i < packageNames.length; ++i) {
PySystemState.add_package(packageNames[i]);
}
} catch (Exception e) {
Log.log(e);
}
}
private File getPluginRootDir() {
try {
IPath relative = new Path(".");
return getBundleInfo().getRelativePath(relative);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* This method is called when the plug-in is stopped
*/
public void stop(BundleContext context) throws Exception {
super.stop(context);
plugin = null;
}
/**
* Returns the shared instance.
*/
public static JythonPlugin getDefault() {
return plugin;
}
public static File getJythonLibDir(){
try {
IPath relative = new Path("Lib");
return getBundleInfo().getRelativePath(relative);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static File getFileWithinJySrc(String f){
try {
IPath relative = new Path("jysrc").addTrailingSeparator().append(f);
return getBundleInfo().getRelativePath(relative);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* @return the jysrc (org.python.pydev.jython/jysrc) directory
*/
public static File getJySrcDirFile() {
try {
IPath relative = new Path("jysrc");
return getBundleInfo().getRelativePath(relative);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* This is a helper for:
* - Loading a file from the filesystem with jython code
* - Compiling it to a code object (that will remain in the 'code' local for the interpreter)
* - Making a call to exec that code
* - Returning the local in the interpreter regarded as jythonResult
*
* Additional notes:
* - The code object will be regenerated only if:
* - It still didn't exist (dought!!)
* - The timestamp of the file changed
*
* @param locals Those are the locals that should be added to the interpreter before calling the actual code
* @param fileToExec the file that should be executed (relative to the JythonPlugin jysrc folder)
* @param interpreter the interpreter that should be used to execute the code
*
# @note If further info is needed (after the run), the interpreter itself should be checked for return values
* @return any error that happened while executing the script
*
*/
public static Throwable exec(HashMap<String, Object> locals, String fileToExec, IPythonInterpreter interpreter) {
File fileWithinJySrc = JythonPlugin.getFileWithinJySrc(fileToExec);
return exec(locals, interpreter, fileWithinJySrc, new File[]{fileWithinJySrc.getParentFile()});
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -