001: // Copyright (c) Corporation for National Research Initiatives
002:
003: package org.python.core;
004:
005: import java.util.Vector;
006:
007: /**
008: * Utility class for loading of compiled python modules and java classes defined
009: * in python modules.
010: */
011: public class BytecodeLoader {
012:
013: static Vector init() {
014: Vector parents = new Vector();
015: parents.addElement(imp.getSyspathJavaLoader());
016: return parents;
017: }
018:
019: static Class findParentClass(Vector parents, String name)
020: throws ClassNotFoundException {
021: for (int i = 0; i < parents.size(); i++) {
022: try {
023: return ((ClassLoader) parents.elementAt(i))
024: .loadClass(name);
025: } catch (ClassNotFoundException e) {
026: }
027: }
028: // couldn't find the .class file on sys.path
029: throw new ClassNotFoundException(name);
030: }
031:
032: static void compileClass(Class c) {
033: // This method has caused much trouble. Using it breaks jdk1.2rc1
034: // Not using it can make SUN's jdk1.1.6 JIT slightly unhappy.
035: // Don't use by default, but allow python.options.compileClass to
036: // override
037: if (!Options.skipCompile) {
038: // System.err.println("compile: "+name);
039: Compiler.compileClass(c);
040: }
041: }
042:
043: private static Class loaderClass = null;
044:
045: private static Loader makeLoader() {
046: if (loaderClass == null) {
047: synchronized (BytecodeLoader.class) {
048: String version = System.getProperty("java.version");
049: if (version.compareTo("1.2") >= 0) {
050: try {
051: loaderClass = Class
052: .forName("org.python.core.BytecodeLoader2");
053: } catch (Throwable e) {
054: loaderClass = BytecodeLoader1.class;
055: }
056: } else
057: loaderClass = BytecodeLoader1.class;
058: }
059: }
060: try {
061: return (Loader) loaderClass.newInstance();
062: } catch (Exception e) {
063: return new BytecodeLoader1();
064: }
065: }
066:
067: /**
068: * Turn the java byte code in data into a java class.
069: *
070: * @param name the name of the class
071: * @param referents a list of superclass and interfaces that the new class
072: * will reference.
073: * @param data the java byte code.
074: */
075: public static Class makeClass(String name, Vector referents,
076: byte[] data) {
077: Loader loader = makeLoader();
078:
079: if (referents != null) {
080: for (int i = 0; i < referents.size(); i++) {
081: try {
082: Class cls = (Class) referents.elementAt(i);
083: ClassLoader cur = cls.getClassLoader();
084: if (cur != null) {
085: loader.addParent(cur);
086: }
087: } catch (SecurityException e) {
088: }
089: }
090: }
091: return loader.loadClassFromBytes(name, data);
092: }
093:
094: /**
095: * Turn the java byte code for a compiled python module into a java class.
096: *
097: * @param name the name of the class
098: * @param data the java byte code.
099: */
100: public static PyCode makeCode(String name, byte[] data,
101: String filename) {
102: try {
103: Class c = makeClass(name, null, data);
104: Object o = c.getConstructor(new Class[] { String.class })
105: .newInstance(new Object[] { filename });
106: return ((PyRunnable) o).getMain();
107: } catch (Exception e) {
108: throw Py.JavaError(e);
109: }
110: }
111: }
|