📄 pyjavaclass.java
字号:
// Copyright (c) Corporation for National Research Initiativespackage org.python.core;import java.lang.reflect.*;import java.beans.*;/** * A wrapper around a java class. */public class PyJavaClass extends PyClass{ public PyReflectedConstructor __init__; public PackageManager __mgr__; private static InternalTables tbl; public synchronized final static InternalTables getInternalTables() { if(tbl == null) tbl = InternalTables.createInternalTables(); return tbl; } public final boolean isLazy() { return proxyClass == null; } public static final PyJavaClass lookup(String name,PackageManager mgr) { if (tbl.queryCanonical(name)) { return lookup(mgr.findClass(null,name,"forced java class")); } PyJavaClass ret = new PyJavaClass(name, mgr); tbl.putLazyCanonical(name, ret); return ret; } public synchronized static final PyJavaClass lookup(Class c) { if (tbl == null) { tbl = InternalTables.createInternalTables(); PyJavaClass jc = new PyJavaClass(true); jc.init(PyJavaClass.class); tbl.putCanonical(PyJavaClass.class,jc); } PyJavaClass ret = tbl.getCanonical(c); if (ret != null) return ret; PyJavaClass lazy = tbl.getLazyCanonical(c.getName()); if (lazy != null) { initLazy(lazy); if (lazy.proxyClass == c) return lazy; } Class parent = c.getDeclaringClass(); if (parent == null) ret = new PyJavaClass(c); else ret = new PyJavaInnerClass(c, lookup(parent)); tbl.putCanonical(c,ret); return ret; } public static PyClass __class__; private PyJavaClass(boolean fakeArg) { super(true); } protected PyJavaClass(Class c) { super(__class__); init(c); } protected PyJavaClass(String name,PackageManager mgr) { super(__class__); __name__ = name; this.__mgr__ = mgr; } protected void findModule(PyObject dict) {} protected Class getProxyClass() { initialize(); return proxyClass; } private static final void initLazy(PyJavaClass jc) { jc.init(jc.__mgr__.findClass(null,jc.__name__,"lazy java class")); tbl.putCanonical(jc.proxyClass,jc); jc.__mgr__ = null; } private boolean initialized=false; // Prevent recursive calls to initialize() private boolean initializing=false; private synchronized void initialize() { if (initialized || initializing) return; initializing = true; synchronized(PyJavaClass.class) { if (proxyClass == null) { initLazy(this); } } init__bases__(proxyClass); init__dict__(); if (ClassDictInit.class.isAssignableFrom(proxyClass) && proxyClass != ClassDictInit.class) { try { Method m = proxyClass.getMethod("classDictInit", new Class[] { PyObject.class }); m.invoke(null, new Object[] { __dict__ }); } catch (Exception exc) { // System.err.println("Got exception: " + exc + " " + // proxyClass); throw Py.JavaError(exc); } } if (InitModule.class.isAssignableFrom(proxyClass)) { try { InitModule m = (InitModule)proxyClass.newInstance(); m.initModule(__dict__); } catch (Exception exc) {// System.err.println("Got exception: " + exc); throw Py.JavaError(exc); } } initialized = true; initializing = false; } private synchronized void init__dict__() { if (__dict__ != null) return; PyStringMap d = new PyStringMap();// d.__setitem__("__module__", Py.None); __dict__ = d; try { Method[] methods = getAccessibleMethods(proxyClass); setBeanInfoCustom(proxyClass, methods); setFields(proxyClass); setMethods(proxyClass, methods); } catch (SecurityException se) {} } private synchronized void init__class__(Class c) { if (!PyObject.class.isAssignableFrom(c)) return; try { Field field = c.getField("__class__"); if (Modifier.isStatic(field.getModifiers()) && field.getType().isAssignableFrom(PyJavaClass.class) && field.getDeclaringClass() == c) { field.set(null, this); } } catch (NoSuchFieldException exc) {} catch (IllegalAccessException exc1) {} } private synchronized void init__bases__(Class c) { if (__bases__ != null) return; Class interfaces[] = getAccessibleInterfaces(c); int nInterfaces = interfaces.length; int nBases = 0; int i; for (i=0; i<nInterfaces; i++) { Class inter = interfaces[i]; if (inter == InitModule.class || inter == PyProxy.class || inter == ClassDictInit.class) continue; nBases++; } Class superclass = c.getSuperclass(); int index=0; PyObject[] bases; PyJavaClass tmp; if (superclass == null || superclass == PyObject.class) { bases = new PyObject[nBases]; } else { bases = new PyObject[nBases+1]; tmp = PyJavaClass.lookup(superclass); bases[0] = tmp; tmp.initialize(); index++; } for (i=0; i<nInterfaces; i++) { Class inter = interfaces[i]; if (inter == InitModule.class || inter == PyProxy.class || inter == ClassDictInit.class) continue; tmp = PyJavaClass.lookup(inter); tmp.initialize(); bases[index++] = tmp; } __bases__ = new PyTuple(bases); } private void init(Class c) { init__class__(c); proxyClass = c; __name__ = c.getName(); } /** * Return the list of all accessible interfaces for a class. This will * only the public interfaces. Since we can't set accessibility on * interfaces, the Options.respectJavaAccessibility is not honored. */ private static Class[] getAccessibleInterfaces(Class c) { // can't modify accessibility of interfaces in Java2 // thus get only public interfaces Class[] in = c.getInterfaces(); java.util.Vector v=new java.util.Vector(); for (int i = 0; i < in.length; i++) { if (!Modifier.isPublic(in[i].getModifiers())) continue; v.addElement(in[i]); } if (v.size() == in.length) return in; Class[] ret = new Class[v.size()]; v.copyInto(ret); return ret; } /** * Return the list of all accessible fields for a class. This will * only the public fields unless Options.respectJavaAccessibility is * false, in which case all fields are returned. */ private static Field[] getAccessibleFields(Class c) { if (!JavaAccessibility.accessIsMutable()) // returns just the public fields return c.getFields(); // from here on out we know we must be using at least Java 1.2. // Note that an ArrayList would be better here because we don't // need access to be synchronized, but that would prevent this file // from being compiled on Java 1.1 (as opposed to being compilable, // but not having the feature available). java.util.Vector fields = new java.util.Vector(); while (c != null) { // get all declared fields for this class, mutate their // accessibility and pop it into the array for later Field[] declared = c.getDeclaredFields(); for (int i=0; i < declared.length; i++) { // TBD: this is a permanent change. Should we provide a // way to restore the original accessibility flag? JavaAccessibility.setAccessible(declared[i], true); fields.addElement(declared[i]); } // walk down superclass chain. no need to deal specially with // interfaces... c = c.getSuperclass(); }// return (Field[])fields.toArray(new Field[fields.size()]); Field[] ret = new Field[fields.size()]; fields.copyInto(ret); return ret; } private void setFields(Class c) { Field[] fields = getAccessibleFields(c); for (int i=0; i<fields.length; i++) { Field field = fields[i]; if (field.getDeclaringClass() != c) continue; String name = getName(field.getName()); boolean isstatic = Modifier.isStatic(field.getModifiers()); if (isstatic) { if (name.startsWith("__doc__") && name.length() > 7) continue; PyObject prop = lookup(name, false); if (prop != null && prop instanceof PyBeanProperty) { PyBeanProperty beanProp = ((PyBeanProperty)prop).copy(); beanProp.field = field; __dict__.__setitem__(name, beanProp); continue; } } __dict__.__setitem__(name, new PyReflectedField(field)); } } /* Produce a good Python name for a Java method. If the Java method ends in '$', strip it (this handles reserved Java keywords) Don't make any changes to keywords since this is now handled by parser */ private String getName(String name) { if (name.endsWith("$")) name = name.substring(0, name.length()-1); return name.intern(); } private void addMethod(Method meth) { String name = getName(meth.getName()); if (name == "_getPyInstance" || name == "_setPyInstance" || name == "_getPySystemState" || name == "_setPySystemState") { return; } // Special case to handle a few troublesome methods in java.awt.*. // These methods are all deprecated and interfere too badly with // bean properties to be tolerated. This is totally a hack, but a // lot of code that uses java.awt will break without it. String classname = proxyClass.getName(); if (classname.startsWith("java.awt.") && classname.indexOf('.', 9) == -1) { if (name == "layout" || name == "insets" || name == "size" || name == "minimumSize" || name == "preferredSize" || name == "maximumSize" || name == "bounds" || name == "enable") { return; } } // See if any of my superclasses are using 'name' for something // else. Or if I'm already using it myself PyObject o = lookup(name, false); // If it's being used as a function, then things get more // interesting... PyReflectedFunction func; if (o != null && o instanceof PyReflectedFunction) { func = (PyReflectedFunction)o; PyObject o1 = __dict__.__finditem__(name); /* If this function already exists, add this method to the signature. If this alters the signature of the function in some significant way, then return a duplicate and stick it in the __dict__ */ if (o1 != o) { if (func.handles(meth)) return; func = func.copy(); } func.addMethod(meth); } else { func = new PyReflectedFunction(meth); try { Field docField = proxyClass.getField("__doc__" + name); int mods = docField.getModifiers(); if (docField.getType() == PyString.class && Modifier.isPublic(mods) && Modifier.isStatic(mods)); func.__doc__ = (PyString) docField.get(null); } catch (NoSuchFieldException ex) { } catch (SecurityException ex) { } catch (IllegalAccessException ex) {} } __dict__.__setitem__(name, func); } /** * Return the list of all accessible methods for a class. This will * only the public methods unless Options.respectJavaAccessibility is * false, in which case all methods are returned. */ private static Method[] getAccessibleMethods(Class c) { if (!JavaAccessibility.accessIsMutable()) // returns just the public methods return c.getMethods(); Method[] declared = c.getDeclaredMethods(); for (int i=0; i < declared.length; i++) { // TBD: this is a permanent change. Should we provide a way to // restore the original accessibility flag? JavaAccessibility.setAccessible(declared[i], true); } return declared; } private boolean ignoreMethod(Method method) { Class[] exceptions = method.getExceptionTypes(); for (int j = 0; j < exceptions.length; j++) { if (exceptions[j] == PyIgnoreMethodTag.class) { return true; } } return false; } /* Add all methods declared by this class */ private void setMethods(Class c, Method[] methods) { for (int i=0; i<methods.length; i++) { Method method = methods[i]; Class dc = method.getDeclaringClass(); if (dc != c) continue; if (ignoreMethod(method)) continue; addMethod(method); } } /* Adds a bean property to this class */ void addProperty(String name, Class propClass, Method getMethod, Method setMethod) { // This will skip indexed property types if (propClass == null) return; boolean set = true; name = getName(name); PyBeanProperty prop = new PyBeanProperty(name, propClass, getMethod, setMethod); // Check to see if this name is already being used... PyObject o = lookup(name, false); if (o != null) { if (!(o instanceof PyReflectedField))
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -