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

com.shipdream.lib.android.mvc.event.bus.internal.EventBusImpl Maven / Gradle / Ivy

/*
 * Copyright 2015 Kejun Xia
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.shipdream.lib.android.mvc.event.bus.internal;

import com.shipdream.lib.android.mvc.event.bus.EventBus;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.LinkedHashMap;
import java.util.Map;

public class EventBusImpl implements EventBus {
    Map, Map> subscribers = new LinkedHashMap<>();
    private Logger logger = LoggerFactory.getLogger(getClass());

    public void register(Object subscriber) {
        if(subscriber == null) {
            throw new IllegalArgumentException("Subscriber registering to an event bus must not be NULL");
        }

        Class subscriberClass = subscriber.getClass();

        while (subscriberClass != null) {
            String name = subscriberClass.getName();
            if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
                // Ignore system classes
                break;
            }

            Method[] methods = subscriberClass.getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().equals("onEvent") && method.getParameterTypes().length == 1) {
                    Class eventType = method.getParameterTypes()[0];

                    Map subs = subscribers.get(eventType);
                    if (subs == null) {
                        subs = new LinkedHashMap<>();
                        subscribers.put(eventType, subs);
                    }

                    subs.put(subscriber, method);
                }
            }

            subscriberClass = subscriberClass.getSuperclass();
        }
    }

    public void unregister(Object subscriber) {
        if(subscriber == null) {
            throw new IllegalArgumentException("Subscriber unregistering to an event bus must not be NULL");
        }

        Class subscriberClass = subscriber.getClass();
        while (subscriberClass != null) {
            String name = subscriberClass.getName();
            if (name.startsWith("java.") || name.startsWith("javax.") || name.startsWith("android.")) {
                // Ignore system classes
                break;
            }

            Method[] methods = subscriberClass.getDeclaredMethods();
            for (Method method : methods) {
                if (method.getName().equals("onEvent") && method.getParameterTypes().length == 1) {
                    Class eventType = method.getParameterTypes()[0];
                    Map subs = subscribers.get(eventType);

                    if(subs != null) {
                        subs.remove(subscriber);
                        if (subs.isEmpty()) {
                            subscribers.remove(eventType);
                        }
                    }
                }
            }

            subscriberClass = subscriberClass.getSuperclass();
        }
    }

    public void post(Object event) {
        if(event == null) {
            throw new IllegalArgumentException("Event bus can't post a NULL event");
        }

        Map subs = subscribers.get(event.getClass());
        if(subs != null) {
            for (Map.Entry entry : subs.entrySet()) {
                entry.getValue().setAccessible(true);
                try {
                    entry.getValue().invoke(entry.getKey(), event);
                } catch (IllegalAccessException e) {
                    logger.warn(e.getMessage(), e);
                } catch (InvocationTargetException e) {
                    throw new RuntimeException("Not able to post event - "
                            + event.getClass().getName() + " due to error: " + e.getMessage(), e);
                }
            }
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy