Index: PackageManager.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PackageManager.java,v retrieving revision 2.4 diff -c -5 -r2.4 PackageManager.java *** PackageManager.java 2000/11/25 21:11:43 2.4 --- PackageManager.java 2000/12/11 13:02:21 *************** *** 57,67 **** PyList clsNames = cls.keys(); for(int i=0; i < clsNames.__len__(); i++) { PyObject name = clsNames.get(i); ! if(!dict.has_key(name)) jpkg.addLazyClass(name.toString()); } return dict.keys(); } --- 57,67 ---- PyList clsNames = cls.keys(); for(int i=0; i < clsNames.__len__(); i++) { PyObject name = clsNames.get(i); ! if(!dict.has_key(name)) jpkg.addLazyClass(name.toString(), this); } return dict.keys(); } Index: PathPackageManager.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PathPackageManager.java,v retrieving revision 1.2 diff -c -5 -r1.2 PathPackageManager.java *** PathPackageManager.java 2000/11/25 21:11:43 1.2 --- PathPackageManager.java 2000/12/11 13:02:22 *************** *** 92,102 **** } } if(instantiate) { if(pkgCand) jpkg.addPackage(jname); ! else jpkg.addLazyClass(jname); } ret.append(name); } --- 92,102 ---- } } if(instantiate) { if(pkgCand) jpkg.addPackage(jname); ! else jpkg.addLazyClass(jname, this); } ret.append(name); } Index: PyJavaClass.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyJavaClass.java,v retrieving revision 2.26 diff -c -5 -r2.26 PyJavaClass.java *** PyJavaClass.java 2000/12/05 18:52:48 2.26 --- PyJavaClass.java 2000/12/11 13:02:26 *************** *** 1,62 **** // Copyright © Corporation for National Research Initiatives package org.python.core; import java.lang.reflect.*; import java.beans.*; public class PyJavaClass extends PyClass { public PyReflectedConstructor __init__; - private static java.util.Hashtable classes; - - public static final PyJavaClass lookup(Class c) { - return lookup(c.getName(), c); - } - - public synchronized static final PyJavaClass lookup(String name, Class c) { - if (classes == null) { - classes = new java.util.Hashtable(); - PyJavaClass jc = new PyJavaClass(true); - classes.put("org.python.core.PyJavaClass", jc); - jc.init(PyJavaClass.class); - Py.initPython(); - } - PyJavaClass ret = (PyJavaClass)classes.get(name); - if (ret != null) - return ret; - ret = new PyJavaClass(name); - classes.put(name, ret); - if (c != null) { - ret.init(c); - } - return ret; - } - public static PyClass __class__; - public PyJavaClass(PyClass c) { - super(c); - } - - public PyJavaClass() { - this(__class__); - } private PyJavaClass(boolean fakeArg) { ! super(true); } ! public PyJavaClass(Class c) { ! this(); init(c); } ! public PyJavaClass(String name) { ! this(); __name__ = name; } protected void findModule(PyObject dict) {} protected Class getProxyClass() { --- 1,38 ---- // Copyright © Corporation for National Research Initiatives package org.python.core; import java.lang.reflect.*; import java.beans.*; + import java.util.*; public class PyJavaClass extends PyClass { public PyReflectedConstructor __init__; public static PyClass __class__; + + /** + * A package manager used when a lazy loaded class must be resolved. + * Is only assigned for uninitialized lazy loaded classes. + */ + private PackageManager mgr = null; private PyJavaClass(boolean fakeArg) { ! super(fakeArg); } ! protected PyJavaClass(Class c) { ! super(__class__); init(c); } ! private PyJavaClass(String name, PackageManager mgr) { ! super(__class__); __name__ = name; + this.mgr = mgr; } protected void findModule(PyObject dict) {} protected Class getProxyClass() { *************** *** 72,82 **** private synchronized void initialize() { if (initialized || initializing) return; initializing = true; if (proxyClass == null) { ! init(Py.findClassEx(__name__)); } init__bases__(proxyClass); init__dict__(); if (ClassDictInit.class.isAssignableFrom(proxyClass) --- 48,61 ---- private synchronized void initialize() { if (initialized || initializing) return; initializing = true; if (proxyClass == null) { ! // This is a lazy loaded class. ! init(mgr.findClass(null, __name__)); ! add_class(__name__, proxyClass, this); ! mgr = null; } init__bases__(proxyClass); init__dict__(); if (ClassDictInit.class.isAssignableFrom(proxyClass) *************** *** 779,785 **** --- 758,906 ---- return super.__tojava__(c); } public String toString() { return ""; + } + + + + + /** + * The "classes" mapping contain three different entry types: + *
    + *
  1. Class -> PyJavaClass. The normal entry that maps a + * a Class to its PyJavaClass. + *
  2. String -> PyJavaClass. A lazy loaded entry. The string is + * the name of the class. Such a lazy entry is only created + * if no other entry exists with the same name. + * When the lazy loaded class is initialized, it inserts a + * #1 entry and replaces this entry with a type #3 entry. + *
  3. String -> Integer. The integer tell how many classes + * with this name that exists in the mapping. + *
+ *

+ * The effect is one level of lazy loaded classes. If the same + * set of classes is lazy loaded from another source, both sets + * of lazy loaded classes will be initialized. + */ + private static java.util.Hashtable classes; + + /** + * Add a loaded class. If some other class with this name already + * exists as a lazy loaded class, the other class will be resolved + * and if the resolved. + * mgr is use to resolve the class. + * If some other class with this name is already loaded, the lazyness + * abandoned and both classses will be resolved. + */ + public synchronized static PyJavaClass lookup(Class c) { + if (classes == null) { + classes = new java.util.Hashtable(); + PyJavaClass jc = new PyJavaClass(true); + add_class("org.python.core.PyJavaClass", PyJavaClass.class, jc); + jc.init(PyJavaClass.class); + } + PyJavaClass ret = (PyJavaClass)classes.get(c); + if (ret != null) + return ret; + String name = c.getName(); + Object v = classes.get(name); + if (v != null) { + if (v instanceof PyJavaClass) { + // Some class with the same have lazy loaded. + PyJavaClass otherclass = (PyJavaClass) v; + // Resolve the lazy class + otherclass.initialize(); + if (otherclass.proxyClass == c) { + // The lazy loaded class was me! + return otherclass; + } + } else { + int i = ((Integer)v).intValue() + 1; + classes.put(name, new Integer(i)); + } + } else { + classes.put(name, new Integer(1)); + } + + ret = new PyJavaClass(c); + classes.put(c, ret); + return ret; + } + + /** + * Add a lazy loaded class. When the class is needed, the package manager + * mgr is use to resolve the class. + * If some other class with this name is already loaded, the lazyness + * abandoned and both classses will be resolved. + */ + public synchronized static PyJavaClass lookup(String name, PackageManager mgr) { + Object v = classes.get(name); + if (v != null) { + if (v instanceof PyJavaClass) { + // Some other class with the same name is already lazy loaded. + PyJavaClass otherclass = (PyJavaClass) v; + otherclass.initialize(); + } + Class c = mgr.findClass(null, name); + return lookup(c); + } + PyJavaClass ret = new PyJavaClass(name, mgr); + classes.put(name, ret); + return ret; + } + + /** + * Initialize a normal initialized entry. + * This is only a separate method so that it can be + * synchronized in the same way is the lookup() methods. + */ + private synchronized static void add_class(String name, Class cls, PyJavaClass pycls) { + classes.put(name, new Integer(1)); + classes.put(cls, pycls); + } + + public synchronized static void flush(PyJavaClass cls) { + String name = cls.__name__; + Object v = classes.get(name); + + if (v instanceof PyJavaClass) { + //assert cls == v + if (cls != v) + Py.writeError("classes", "Internal inconsistence #1 in flush"); + classes.remove(name); + } else { + int i = ((Integer)v).intValue() - 1; + if (i > 0) + classes.put(name, new Integer(i)); + else + classes.remove(name); + + if (cls.proxyClass == null) + Py.writeError("classes", "Internal inconsistence #2 in flush"); + classes.remove(cls.proxyClass); + } + } + + public synchronized static final void dump() { + for (Enumeration e = classes.keys(); e.hasMoreElements(); ) { + Object k = e.nextElement(); + System.out.println(k + ": " + classes.get(k)); + } + } + + public synchronized static final void dumpDebug() { + for (Enumeration e = classes.keys(); e.hasMoreElements(); ) { + Object k = e.nextElement(); + if (k instanceof Class) + continue; + Object v = classes.get(k); + if (v instanceof PyJavaClass) + System.out.println(k + ": lazyloaded"); + else { + if (((Integer)v).intValue() != 1) + System.out.println(k + ": " + v); + } + } } } Index: PyJavaInnerClass.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyJavaInnerClass.java,v retrieving revision 2.6 diff -c -5 -r2.6 PyJavaInnerClass.java *** PyJavaInnerClass.java 1999/11/10 18:18:02 2.6 --- PyJavaInnerClass.java 2000/12/11 13:02:26 *************** *** 4,14 **** public class PyJavaInnerClass extends PyJavaClass { public PyJavaClass parent = null; public PyJavaInnerClass(Class c, PyJavaClass parent) { ! init(c); this.parent = parent; int dollar = __name__.indexOf('$'); if (dollar != -1) { __name__ = __name__.substring(0, dollar)+ "." + __name__.substring(dollar+1, __name__.length()); --- 4,14 ---- public class PyJavaInnerClass extends PyJavaClass { public PyJavaClass parent = null; public PyJavaInnerClass(Class c, PyJavaClass parent) { ! super(c); this.parent = parent; int dollar = __name__.indexOf('$'); if (dollar != -1) { __name__ = __name__.substring(0, dollar)+ "." + __name__.substring(dollar+1, __name__.length()); Index: PyJavaPackage.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/PyJavaPackage.java,v retrieving revision 2.4 diff -c -5 -r2.4 PyJavaPackage.java *** PyJavaPackage.java 2000/11/25 21:11:43 2.4 --- PyJavaPackage.java 2000/12/11 13:02:27 *************** *** 82,93 **** PyObject ret = PyJavaClass.lookup(c); __dict__.__setitem__(name.intern(), ret); return ret; } ! public PyObject addLazyClass(String name) { ! PyObject ret = PyJavaClass.lookup(__name__+'.'+name,null); __dict__.__setitem__(name.intern(), ret); return ret; } /** Add statically known classes. --- 82,93 ---- PyObject ret = PyJavaClass.lookup(c); __dict__.__setitem__(name.intern(), ret); return ret; } ! public PyObject addLazyClass(String name, PackageManager mgr) { ! PyObject ret = PyJavaClass.lookup(__name__+'.'+name, mgr); __dict__.__setitem__(name.intern(), ret); return ret; } /** Add statically known classes. Index: SysPackageManager.java =================================================================== RCS file: /cvsroot/jython/jython/org/python/core/SysPackageManager.java,v retrieving revision 1.2 diff -c -5 -r1.2 SysPackageManager.java *** SysPackageManager.java 2000/11/25 21:11:43 1.2 --- SysPackageManager.java 2000/12/11 13:02:27 *************** *** 74,85 **** if (fakepath != null) addClassPath(fakepath); } public Class findClass(String pkg,String name) { Class c; ! if (pkg.length()>0) c = Py.findClassEx(pkg+'.'+name); ! else c = Py.findClassEx(name); return c; } public PyList doDir(PyJavaPackage jpkg,boolean instantiate,boolean exclpkgs) { --- 74,87 ---- if (fakepath != null) addClassPath(fakepath); } public Class findClass(String pkg,String name) { Class c; ! if (pkg != null && pkg.length()>0) ! c = Py.findClassEx(pkg+'.'+name); ! else ! c = Py.findClassEx(name); return c; } public PyList doDir(PyJavaPackage jpkg,boolean instantiate,boolean exclpkgs) {