// Copyright (c) Corporation for National Research Initiatives package org.python.core; import java.lang.ref.WeakReference; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.util.Map; import java.util.WeakHashMap; import org.python.util.Generic; public class PyBeanEventProperty extends PyObject { private static Map<String, Class<?>> adapterClasses = Generic.map(); private static Map<Object, Map<String, WeakReference<Object>>> adapters = new WeakHashMap<Object, Map<String, WeakReference<Object>>>(); public Method addMethod; public String eventName; public Class<?> eventClass; public String __name__; private Field adapterField; private Class<?> adapterClass; public PyBeanEventProperty(String eventName, Class<?> eventClass, Method addMethod, Method eventMethod) { __name__ = eventMethod.getName().intern(); this.addMethod = addMethod; this.eventName = eventName; this.eventClass = eventClass; } @Override public PyObject _doget(PyObject self) { if (self == null) { return this; } initAdapter(); Object jself = Py.tojava(self, addMethod.getDeclaringClass()); Object field; try { field = adapterField.get(getAdapter(jself)); } catch (Exception exc) { throw Py.JavaError(exc); } PyCompoundCallable func; if (field == null) { func = new PyCompoundCallable(); setFunction(jself, func); return func; } if (field instanceof PyCompoundCallable) { return (PyCompoundCallable)field; } func = new PyCompoundCallable(); setFunction(jself, func); func.append((PyObject)field); return func; } @Override public boolean _doset(PyObject self, PyObject value) { Object jself = Py.tojava(self, addMethod.getDeclaringClass()); if (!(value instanceof PyCompoundCallable)) { PyCompoundCallable func = new PyCompoundCallable(); setFunction(jself, func); func.append(value); } else { setFunction(jself, value); } return true; } @Override public String toString() { return "<beanEventProperty " + __name__ + " for event " + eventClass.toString() + " " + Py.idstr(this) + ">"; } private Object getAdapter(Object o, String evc) { Map<String, WeakReference<Object>> ads = adapters.get(o); if (ads == null) { return null; } WeakReference<Object> adw = ads.get(evc); if (adw == null) { return null; } return adw.get(); } private void putAdapter(Object o, String evc, Object ad) { Map<String, WeakReference<Object>> ads = adapters.get(o); if (ads == null) { ads = Generic.map(); adapters.put(o, ads); } ads.put(evc, new WeakReference<Object>(ad)); } private synchronized Object getAdapter(Object self) { String eventClassName = eventClass.getName(); Object adapter = getAdapter(self, eventClassName); if (adapter != null) { return adapter; } try { adapter = adapterClass.newInstance(); addMethod.invoke(self, adapter); } catch (Exception e) { throw Py.JavaError(e); } putAdapter(self, eventClassName, adapter); return adapter; } private void initAdapter() { if (adapterClass == null) { adapterClass = getAdapterClass(eventClass); try { adapterField = adapterClass.getField(__name__); } catch (NoSuchFieldException exc) { throw Py.AttributeError("Internal bean event error: " + __name__); } } } private void setFunction(Object self, PyObject callable) { initAdapter(); try { adapterField.set(getAdapter(self), callable); } catch (Exception exc) { throw Py.JavaError(exc); } } private synchronized static Class<?> getAdapterClass(Class<?> c) { String name = "org.python.proxies." + c.getName() + "$Adapter"; Class<?> pc = Py.findClass(name); if (pc == null) { pc = adapterClasses.get(name); if (pc == null) { pc = MakeProxies.makeAdapter(c); adapterClasses.put(name, pc); } } return pc; } }