All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.yestech.event.multicaster.DefaultEventMulticaster Maven / Gradle / Ivy

Go to download

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 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 event, IListener listener) {
        listenerMap.put(event, new ListenerAdapter(listener));
    }

    private void reorderListeners(Map> tempListenerMap) {
        for (Map.Entry> tempEntry : tempListenerMap.entrySet()) {
            Class 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());
        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy