// 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;
}
}