blob: 7cd7c3a8916ac60a4b5334555a4b4626760550b1 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.e4.tools.event.spy.core;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.tools.event.spy.model.CapturedEvent;
import org.eclipse.e4.tools.event.spy.model.CapturedEventFilter;
import org.eclipse.e4.ui.internal.workbench.UIEventPublisher;
import org.eclipse.e4.ui.services.internal.events.EventBroker;
import org.eclipse.e4.ui.workbench.UIEvents;
import org.osgi.service.event.Event;
import org.osgi.service.event.EventHandler;
@SuppressWarnings("restriction")
public class EventMonitor {
public interface NewEventListener {
void newEvent(CapturedEvent event);
}
private final static String TOPIC = UIEvents.UITopicBase + UIEvents.TOPIC_SEP + UIEvents.ALL_SUB_TOPICS;
@SuppressWarnings({"serial"})
private static Set<Integer> EVENT_HELPER_CLASSES = new HashSet<Integer>() {{
add(UIEvents.class.getName().hashCode());
add(UIEventPublisher.class.getName().hashCode());
}};
private Collection<CapturedEventFilter> filters;
private final IEventBroker eventBroker;
private NewEventListener listener;
private CapturedEventFilterMatcher eventFilterMatcher;
private final EventHandler eventHandler = new EventHandler() {
public void handleEvent(Event event) {
if (listener == null) {
return;
}
CapturedEvent capturedEvent = new CapturedEvent();
capturedEvent.setTopic(event.getTopic());
capturedEvent.setPublisherClassName(getPublisherClassName());
for (String propertyName: event.getPropertyNames()) {
Object value = event.getProperty(propertyName);
capturedEvent.addParameter(propertyName, value);
if (value != null && UIEvents.EventTags.ELEMENT.equals(propertyName)) {
capturedEvent.setChangedElementClassName(value.getClass().getName());
}
}
if (shouldBeCaptured(capturedEvent)) {
listener.newEvent(capturedEvent);
}
}
};
public EventMonitor(IEventBroker eventBroker) {
this.eventBroker = eventBroker;
}
public void start(Collection<CapturedEventFilter> filters) {
this.filters = filters;
eventBroker.subscribe(TOPIC, eventHandler);
}
public void stop() {
eventBroker.unsubscribe(eventHandler);
}
public void setNewEventListener(NewEventListener listener) {
this.listener = listener;
}
private boolean shouldBeCaptured(CapturedEvent event) {
if (filters != null) {
Iterator<CapturedEventFilter> iter = filters.iterator();
while (iter.hasNext()) {
if (!getEventFilterMatcher().matches(event, iter.next())) {
return false;
}
}
}
return true;
}
private String getPublisherClassName() {
StackTraceElement items[] = Thread.currentThread().getStackTrace();
boolean foundEventBroker = false;
for (int i=0; i<items.length; i++) {
String clsName = items[i].getClassName();
if (!foundEventBroker && clsName.equals(EventBroker.class.getName())) {
foundEventBroker = true;
} else if (foundEventBroker) {
if (!EVENT_HELPER_CLASSES.contains(clsName.hashCode())) {
return String.format("%s (%s:%d)", clsName, items[i].getMethodName(), items[i].getLineNumber());
}
}
}
return "";
}
private CapturedEventFilterMatcher getEventFilterMatcher() {
if (eventFilterMatcher == null) {
eventFilterMatcher = new CapturedEventFilterMatcher();
}
return eventFilterMatcher;
}
}