/*******************************************************************************
* Copyright (c) 2008 Ralf Ebert
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Ralf Ebert - initial API and implementation
*******************************************************************************/
package com.swtxml.events.visitor;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Collection;
import org.eclipse.core.runtime.Assert;
import org.eclipse.swt.widgets.Widget;
import com.swtxml.definition.IAttributeDefinition;
import com.swtxml.events.internal.SwtEvents;
import com.swtxml.events.registry.WidgetEventListenerMethod;
import com.swtxml.tinydom.ITagVisitor;
import com.swtxml.tinydom.Tag;
import com.swtxml.util.reflector.Reflector;
import com.swtxml.util.reflector.Subclasses;
import com.swtxml.util.reflector.Visibility;
/**
* CreateEventListeners processes on:eventName="responderMethod" attribute
* values by adding a listener to the widget that delegates the event to a
* method "responder"."responderMethod"(). It only applies to attributes in the
* given namespace and a given event registry.
*
* @author Ralf Ebert <info@ralfebert.de>
*/
public class AddEventListeners implements ITagVisitor {
private Object responder;
private SwtEvents namespace;
public AddEventListeners(Object responder, SwtEvents namespace) {
this.responder = responder;
this.namespace = namespace;
}
public void visit(Tag tag) {
Collection<IAttributeDefinition> events = tag.getAttributes(namespace);
if (!events.isEmpty()) {
Widget widget = tag.getAdapter(Widget.class);
Assert.isNotNull(widget, String.format(
"Tag %s has event attributes %s, but is not a Widget!", tag.getName(), events));
for (IAttributeDefinition eventAttribute : events) {
String responderMethodName = tag.getAttributeValue(namespace, eventAttribute);
setupListener(widget, eventAttribute.getName(), responderMethodName);
}
}
}
/**
* setupListener resolves the event handling method named
* responderMethodName in the responder class. It then creates a SWT
* listener proxy object that delegates to this responder method whenever
* listener.<eventName> is called. This listener is added to the widget.
*/
void setupListener(Widget widget, final String eventName, String responderMethodName) {
WidgetEventListenerMethod event = namespace.getEvents().getWidgetEvent(widget.getClass(),
eventName);
Assert.isNotNull(event, String.format("No event %s in %s found!", eventName, widget
.getClass()));
Method responderMethod = Reflector.findMethods(Visibility.PRIVATE, Subclasses.INCLUDE)
.name(responderMethodName.trim()).optionalParameter(event.getEventClass())
.exactOne(responder.getClass());
InvocationHandler handler = new ListenerDelegatingInvocationHandler(eventName, responder,
responderMethod);
Object listener = Proxy.newProxyInstance(responder.getClass().getClassLoader(),
new Class[] { event.getListenerInterfaceClass() }, handler);
event.addListenerToWidget(widget, listener);
}
}