package org.python.core; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class PyGetSetDescr extends PyDescriptor { private Method get_meth; private Method set_meth; private Method del_meth; private Class getset_type; public PyGetSetDescr(PyType dtype, String name, Class c, String get, String set) { this(dtype, name, c, get, set, null); } public PyGetSetDescr(String name, Class c, String get, String set) { this(PyType.fromClass(c), name, c, get, set, null); } public PyGetSetDescr(PyType dtype, String name, Class c, String get, String set, String del) { this.name = name; this.dtype = dtype; try { get_meth = c.getMethod(get, new Class[] {}); } catch(NoSuchMethodException e) { throw Py.SystemError("method "+get+" doesn't exist: "+c.getName()); } if(Modifier.isStatic(get_meth.getModifiers())) throw Py.SystemError("static "+get+" not supported: "+c.getName()); getset_type = get_meth.getReturnType(); if(set != null) { try { set_meth = c.getMethod(set, new Class[] {getset_type}); } catch(NoSuchMethodException e) { throw Py.SystemError("method "+set+" doesn't exist: "+c.getName()); } if(Modifier.isStatic(set_meth.getModifiers())) throw Py.SystemError("static "+set+" not supported: "+c.getName()); } if(del != null) { try { del_meth = c.getMethod(del, new Class[] {}); } catch(NoSuchMethodException e) { throw Py.SystemError("method "+set+" doesn't exist: "+c.getName()); } if(Modifier.isStatic(del_meth.getModifiers())) throw Py.SystemError("static "+del+" not supported: "+c.getName()); } } public PyGetSetDescr(String name, Class c, String get, String set, String del) { this(PyType.fromClass(c), name, c, get, set, del); } public String toString() { return "<attribute '" + name + "' of '" + dtype.fastGetName() + "' objects>"; } /** * @see org.python.core.PyObject#__get__(org.python.core.PyObject, * org.python.core.PyObject) */ public PyObject __get__(PyObject obj, PyObject type) { try { if(obj != null) { PyType objtype = obj.getType(); if(objtype != dtype && !objtype.isSubType(dtype)) throw get_wrongtype(objtype); Object v = get_meth.invoke(obj, new Object[0]); if(v == null) { obj.noAttributeError(name); } return Py.java2py(v); } return this; } catch(IllegalArgumentException e) { throw Py.JavaError(e); } catch(IllegalAccessException e) { throw Py.JavaError(e); // unexpected } catch(InvocationTargetException e) { throw Py.JavaError(e); } } /** * @see org.python.core.PyObject#__set__(org.python.core.PyObject, * org.python.core.PyObject) */ public void __set__(PyObject obj, PyObject value) { try { // obj != null PyType objtype = obj.getType(); if(objtype != dtype && !objtype.isSubType(dtype)) throw get_wrongtype(objtype); Object converted = value.__tojava__(getset_type); if(converted == Py.NoConversion) { throw Py.TypeError(""); // xxx } set_meth.invoke(obj, new Object[] {converted}); } catch(IllegalArgumentException e) { throw Py.JavaError(e); } catch(IllegalAccessException e) { throw Py.JavaError(e); // unexpected } catch(InvocationTargetException e) { throw Py.JavaError(e); } } public void __delete__(PyObject obj) { try { if(obj != null) { PyType objtype = obj.getType(); if(objtype != dtype && !objtype.isSubType(dtype)) throw get_wrongtype(objtype); del_meth.invoke(obj, new Object[0]); } } catch(IllegalArgumentException e) { throw Py.JavaError(e); } catch(IllegalAccessException e) { throw Py.JavaError(e); // unexpected } catch(InvocationTargetException e) { throw Py.JavaError(e); } } /** * @see org.python.core.PyObject#implementsDescrSet() */ public boolean implementsDescrSet() { return set_meth != null; } public boolean implementsDescrDelete() { return del_meth != null; } /** * @see org.python.core.PyObject#isDataDescr() */ public boolean isDataDescr() { return true; } }