org.yestech.event.multicaster.DefaultEventMulticaster Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of yesevent Show documentation
Show all versions of yesevent Show documentation
Java Based Event framework that can be used with a Dependency Injection system or without. Currently
Spring and Guice are supported. The Framework is pluggable with implementation that support direct routing and integration
of apache camel to handle the routing of events.
The newest version!
/*
* Copyright LGPL3
* YES Technology Association
* http://yestech.org
*
* http://www.opensource.org/licenses/lgpl-3.0.html
*/
package org.yestech.event.multicaster;
import org.yestech.event.annotation.AsyncListener;
import org.yestech.event.*;
import org.yestech.event.listener.BaseListener;
import org.yestech.event.listener.IListener;
import org.yestech.event.event.IEvent;
import com.google.common.collect.ArrayListMultimap;
import static com.google.common.collect.Lists.newArrayList;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
import javax.annotation.PostConstruct;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.yestech.event.annotation.RegisterEvent;
import org.yestech.event.annotation.RegisteredEvents;
import org.springframework.stereotype.Component;
/**
* The default event multicaster implementation this implementation expects all {@link IListener} that wish to be
* executed contain a {@link RegisteredEvents} annotation. It binds to a spring bean with id "eventMulticaster"
*
* @param An implementation of IEvent, The event type the multicaster will handle.
* @param A serializable result that result type can handle.
*/
@Component("eventMulticaster")
public class DefaultEventMulticaster extends BaseEventMulticaster {
private static final Logger logger = LoggerFactory.getLogger(DefaultEventMulticaster.class);
private final Multimap listenerMap = ArrayListMultimap.create();
private List listeners = newArrayList();
@Override
public void registerListener(L listener) {
listeners.add(listener);
}
/**
* Sets a list of {@link IListener}s
*
* @param listeners
*/
public void setListeners(List listeners) {
this.listeners = listeners;
}
public List getListeners() {
return listeners;
}
@PostConstruct
@Override
public void init() {
addListeners(listeners);
initializeThreadPool();
}
protected void addListeners(List listeners) {
Map> tempListenerMap = Maps.newHashMap();
if (listeners != null) {
for (IListener listener : listeners) {
RegisteredEvents listenedEvents = listener.getClass().getAnnotation(RegisteredEvents.class);
if (listenedEvents != null) {
for (RegisterEvent eventClass : listenedEvents.events()) {
Class extends IEvent> event = eventClass.event();
Integer order = eventClass.order();
ListenerContainer container = new ListenerContainer();
container.setListener(listener);
container.setOrder(order);
List tempListenerList = tempListenerMap.get(event);
if (tempListenerList == null) {
tempListenerList = newArrayList();
tempListenerMap.put(event, tempListenerList);
}
tempListenerList.add(container);
}
} else {
String msg = String.format("%s must contain an RegisteredEvents annotation",
listener.getClass().getSimpleName());
logger.error(msg);
throw new InvalidListenerException(msg);
}
}
reorderListeners(tempListenerMap);
}
}
Multimap getListenerMap() {
return listenerMap;
}
@SuppressWarnings({"unchecked"})
@Override
public RESULT process(final EVENT event) {
Collection list = listenerMap.get(event.getClass());
ResultReference ref = new ResultReference();
if (list != null && !list.isEmpty()) {
for (ListenerAdapter listener : list) {
if (listener.isAsync()) {
processAsync(event, ref, listener);
} else {
listener.handle(event, ref);
}
}
}
Object result = ref.getResult();
validate(event, result);
return (RESULT) result;
}
protected void addListener(Class extends IEvent> event, IListener listener) {
listenerMap.put(event, new ListenerAdapter(listener));
}
private void reorderListeners(Map> tempListenerMap) {
for (Map.Entry> tempEntry : tempListenerMap.entrySet()) {
Class extends IEvent> event = tempEntry.getKey();
List tempListenersList = tempEntry.getValue();
Collections.sort(tempListenersList);
for (ListenerContainer listenerContainer : tempListenersList) {
addListener(event, listenerContainer.getListener());
}
}
}
class ListenerAdapter extends BaseListener {
private IListener adaptee;
private boolean async;
public ListenerAdapter(IListener adaptee) {
this.adaptee = adaptee;
async = adaptee.getClass().isAnnotationPresent(AsyncListener.class);
}
public boolean isAsync() {
return async;
}
public IListener getAdaptee() {
return adaptee;
}
@Override
public void handle(IEvent event, ResultReference result) {
adaptee.handle(event, result);
}
@Override
public void deregister() {
getMulticaster().deregisterListener(adaptee);
}
@Override
public void register() {
getMulticaster().registerListener(adaptee);
}
}
private class ListenerContainer implements Comparable {
private IListener listener;
private Integer order;
public IListener getListener() {
return listener;
}
public void setListener(IListener listener) {
this.listener = listener;
}
public Integer getOrder() {
return order;
}
public void setOrder(Integer order) {
this.order = order;
}
@Override
public int compareTo(ListenerContainer compare) {
return order.compareTo(compare.getOrder());
}
}
}