in src/main/java/org/apache/bsf/util/ReflectionUtils.java [88:203]
public static void addEventListener (final Object source, final String eventSetName,
final EventProcessor processor)
throws IntrospectionException, IllegalArgumentException,
IllegalAccessException, InstantiationException,
InvocationTargetException {
// find the event set descriptor for this event
final BeanInfo bi = Introspector.getBeanInfo (source.getClass ());
final EventSetDescriptor arrESD[]=bi.getEventSetDescriptors ();
final EventSetDescriptor esd=(EventSetDescriptor) findFeatureByName ("event", eventSetName, arrESD);
if (esd == null) // no events found, maybe a proxy from OpenOffice.org?
{
String errMsg="event set '" + eventSetName +"' unknown for source type '" + source.getClass () + "': ";
if (arrESD.length==0) // no event sets found in class!
{
errMsg=errMsg+"class does not implement any event methods following Java's event pattern!";
}
else
{
// errMsg=errMsg+"class defines the following event set(s): {";
errMsg=errMsg+"class defines the following event set(s): ";
// sort ESD by Name
final TreeSet ts=new TreeSet(new Comparator () {
public int compare(final Object o1, final Object o2) {return ((EventSetDescriptor)o1).getName().compareToIgnoreCase(((EventSetDescriptor)o2).getName());}
public boolean equals(final Object o1, final Object o2) {return ((EventSetDescriptor)o1).getName().equalsIgnoreCase (((EventSetDescriptor)o2).getName());}
});
for (int i=0;i<arrESD.length;i++)
{
ts.add(arrESD[i]);
}
final Iterator it=ts.iterator(); // get iterator
int i=0;
while (it.hasNext()) // iterate in sorted order
{
final EventSetDescriptor tmpESD=(EventSetDescriptor) it.next();
if (i>0)
{
errMsg=errMsg+", ";
}
errMsg=errMsg+"\n\t"+'\''+tmpESD.getName()+"'={"; // event set name
// iterate over listener methods and display their names in sorted order
final Method m[]=tmpESD.getListenerMethods();
final TreeSet tsM=new TreeSet(new Comparator () {
public int compare(final Object o1, final Object o2) {return ((Method)o1).getName().compareToIgnoreCase(((Method)o2).getName());}
public boolean equals(final Object o1, final Object o2) {return ((Method)o1).getName().equalsIgnoreCase (((Method)o2).getName());}
});
for (int j=0;j<m.length;j++)
{
tsM.add(m[j]);
}
final Iterator itM=tsM.iterator();
int j=0;
while (itM.hasNext())
{
if (j>0)
{
errMsg=errMsg+',';
}
errMsg=errMsg+'\''+((Method) itM.next()).getName()+'\'';
j++;
}
errMsg=errMsg+'}'; // close event method set
i++;
}
errMsg=errMsg+"."; // close set of event sets
}
throw new IllegalArgumentException (errMsg);
}
// get the class object for the event
final Class listenerType=esd.getListenerType(); // get ListenerType class object from EventSetDescriptor
// find an event adapter class of the right type
final Class adapterClass = EventAdapterRegistry.lookup (listenerType);
if (adapterClass == null) {
throw new IllegalArgumentException ("event adapter for listener type " +
"'" + listenerType + "' (eventset " +
"'" + eventSetName + "') unknown");
}
// create the event adapter and give it the event processor
final EventAdapter adapter = (EventAdapter) adapterClass.newInstance ();
adapter.setEventProcessor (processor);
// bind the adapter to the source bean
Method addListenerMethod;
Object[] args;
if (eventSetName.equals ("propertyChange") ||
eventSetName.equals ("vetoableChange")) {
// In Java 1.2, beans may have direct listener adding methods
// for property and vetoable change events which take the
// property name as a filter to be applied at the event source.
// The filter property of the event processor should be used
// in this case to support the source-side filtering.
//
// ** TBD **: the following two lines need to change appropriately
addListenerMethod = esd.getAddListenerMethod ();
args = new Object[] {adapter};
}
else
{
addListenerMethod = esd.getAddListenerMethod ();
args = new Object[] {adapter};
}
addListenerMethod.invoke (source, args);
}