Index: src/org/python/core/PyBeanProperty.java =================================================================== --- src/org/python/core/PyBeanProperty.java (revision 3202) +++ src/org/python/core/PyBeanProperty.java (working copy) @@ -3,18 +3,31 @@ import java.lang.reflect.*; public class PyBeanProperty extends PyReflectedField { - public Method getMethod, setMethod; + public Method getMethod; + public Method[] setMethod; public Class myType; String __name__; public PyBeanProperty(String name, Class myType, - Method getMethod, Method setMethod) + Method getMethod, Method[] setMethod) { __name__ = name; this.getMethod = getMethod; - this.setMethod = setMethod; + if (setMethod != null) { + this.setMethod = setMethod; + } else { + this.setMethod = new Method[0]; + } this.myType = myType; } + + /** additional setters in case of overloading of setters with different argument types. */ + public void addSetter(Method setter) { + Method[] tmp = new Method[setMethod.length+1]; + System.arraycopy(setMethod, 0, tmp, 0, setMethod.length); + tmp[setMethod.length] = setter; + setMethod = tmp; + } public PyObject _doget(PyObject self) { if (self == null) { @@ -46,34 +59,42 @@ throw Py.AttributeError("instance attr: "+__name__); } - if (setMethod == null) { + if (setMethod == null || setMethod.length==0) { throw Py.AttributeError("read-only attr: "+__name__); } + + for(int i = 0; i < setMethod.length; i++) { + Object iself = Py.tojava(self, setMethod[i].getDeclaringClass()); - Object iself = Py.tojava(self, setMethod.getDeclaringClass()); + Object jvalue=null; - Object jvalue=null; + // Special handling of tuples + // try to call a class constructor + if (value instanceof PyTuple) { + try { + PyTuple vtup = (PyTuple)value; + value = PyJavaClass.lookup(myType).__call__(vtup.getArray()); // xxx PyObject subclasses + } catch (Throwable t) { + // If something goes wrong ignore it? + } + } + if (jvalue == null) { + try { + jvalue = Py.tojava(value, setMethod[i].getParameterTypes()[0]); + }catch (PyException e) { + // guess this isn't the right setter + continue; + } + } - // Special handling of tuples - // try to call a class constructor - if (value instanceof PyTuple) { try { - PyTuple vtup = (PyTuple)value; - value = PyJavaClass.lookup(myType).__call__(vtup.getArray()); // xxx PyObject subclasses - } catch (Throwable t) { - // If something goes wrong ignore it? + setMethod[i].invoke(iself, new Object[] {jvalue}); + } catch (Exception e) { + throw Py.JavaError(e); } + return true; } - if (jvalue == null) { - jvalue = Py.tojava(value, myType); - } - - try { - setMethod.invoke(iself, new Object[] {jvalue}); - } catch (Exception e) { - throw Py.JavaError(e); - } - return true; + return false; } public PyBeanProperty copy() { Index: src/org/python/core/PyType.java =================================================================== --- src/org/python/core/PyType.java (revision 3202) +++ src/org/python/core/PyType.java (working copy) @@ -907,6 +907,20 @@ return null; } + private static Method[] get_all_non_static_methods( + Class c, + String name) { + Method[] meth = c.getMethods(); + ArrayList out = new ArrayList(); + for(int i = 0; i < meth.length; i++) { + if (meth[i].getName().equals(name) && + !Modifier.isStatic(meth[i].getModifiers())) { + out.add(meth[i]); + } + } + return (Method[])out.toArray(new Method[0]); + } + private static Method get_descr_method( Class c, String name, @@ -1074,7 +1088,7 @@ continue; } Method getter = null; - Method setter = null; + Method[] setter = null; Class proptype = null; getter = get_non_static_method(c, "get" + propname, new Class[] {}); if(getter == null) @@ -1083,16 +1097,11 @@ new Class[] {}); if(getter != null) { proptype = getter.getReturnType(); - setter = get_non_static_method(c, - "set" + propname, - new Class[] {proptype}); } else { - Object o = propnames.get(propname); - if(o instanceof Method) { - setter = (Method)o; - proptype = setter.getParameterTypes()[0]; - } + proptype = null; } + setter = get_all_non_static_methods(c, + "set" + propname); if(setter != null || getter != null) { dict.__setitem__(npropname, new PyBeanProperty(npropname, proptype, Index: src/org/python/core/PyJavaClass.java =================================================================== --- src/org/python/core/PyJavaClass.java (revision 3202) +++ src/org/python/core/PyJavaClass.java (working copy) @@ -444,7 +444,7 @@ /* Adds a bean property to this class */ void addProperty(String name, Class propClass, - Method getMethod, Method setMethod) + Method getMethod, Method[] setMethod) { // This will skip indexed property types if (propClass == null) @@ -465,11 +465,11 @@ if (o instanceof PyBeanProperty) { PyBeanProperty oldProp = (PyBeanProperty)o; - if (prop.myType == oldProp.myType) { + if (prop.myType == oldProp.myType || oldProp.myType == null) { // If this adds nothing over old property, do nothing if ((prop.getMethod == null || oldProp.getMethod != null) && - (prop.setMethod == null || oldProp.setMethod != null)) + (prop.setMethod.length == 0 || oldProp.setMethod.length != 0)) { set = false; } @@ -480,7 +480,10 @@ prop.getMethod = oldProp.getMethod; } if (oldProp.setMethod != null) { - prop.setMethod = oldProp.setMethod; + Method[] setter = new Method[prop.setMethod.length+oldProp.setMethod.length]; + System.arraycopy(oldProp.setMethod, 0, setter, 0, oldProp.setMethod.length); + System.arraycopy(prop.setMethod, 0, setter, oldProp.setMethod.length, prop.setMethod.length); + prop.setMethod = setter; } } } @@ -592,19 +595,21 @@ PyObject o = __dict__.__finditem__(new PyString(pname)); PyBeanProperty prop; if (o == null || !(o instanceof PyBeanProperty) ) { - addProperty(pname, myType, getter, setter); + if (setter != null) { + addProperty(pname, myType, getter, new Method[] {setter}); + } else { + addProperty(pname, myType, getter, new Method[0]); + } } else { prop = (PyBeanProperty)o; - if (prop.myType != myType) { - if (getter != null) { - addProperty(pname, myType, getter, setter); - } - } else { - if (getter != null) prop.getMethod = getter; - if (setter != null && (ret == Void.TYPE || prop.setMethod==null)) - prop.setMethod = setter; - + if (setter != null && ret == Void.TYPE) { + prop.addSetter(setter); } + + if (getter != null) { + prop.myType = myType; + prop.getMethod = getter; + } } }