org.yestech.event.multicaster.AggregatingEventMulticaster 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.IAggregateListener;
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;
/**
* Aggregating Multicaster. It binds to a spring bean with id "aggregatingEventMulticaster"
*
* @param
* @param
*/
@Component("aggregatingEventMulticaster")
public class AggregatingEventMulticaster extends BaseEventMulticaster {
private static final Logger logger = LoggerFactory.getLogger(AggregatingEventMulticaster.class);
private final Multimap listenerMap = ArrayListMultimap.create();
private List listeners = newArrayList();
@Override
public void registerListener(L listener) {
listeners.add((IAggregateListener) 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 (IAggregateListener 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;
}
@Override
public AggregateResultReference process(EVENT event) {
Collection list = listenerMap.get(event.getClass());
AggregateResultReference aggregateReference = new AggregateResultReference();
if (list != null && !list.isEmpty()) {
for (ListenerAdapter listener : list) {
ResultReference ref = new ResultReference();
if (listener.isAsync()) {
processAsync(event, ref, listener);
} else {
listener.handle(event, ref);
}
Object result = ref.getResult();
validate(event, result);
aggregateReference.addResult(listener.getToken(), ref);
}
}
return aggregateReference;
}
protected void addListener(Class extends IEvent> event, IAggregateListener 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 implements IAggregateListener {
private IAggregateListener adaptee;
private boolean async;
@Override
public Enum getToken() {
return adaptee.getToken();
}
@Override
public void setToken(Enum token) {
adaptee.setToken(token);
}
public ListenerAdapter(IAggregateListener adaptee) {
this.adaptee = adaptee;
async = adaptee.getClass().isAnnotationPresent(AsyncListener.class);
}
public boolean isAsync() {
return async;
}
public IAggregateListener 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 IAggregateListener listener;
private Integer order;
public IAggregateListener getListener() {
return listener;
}
public void setListener(IAggregateListener 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());
}
}
}