com.azaptree.services.eventbus.impl.EventBusServiceImpl.java Source code

Java tutorial

Introduction

Here is the source code for com.azaptree.services.eventbus.impl.EventBusServiceImpl.java

Source

package com.azaptree.services.eventbus.impl;

/*
 * #%L
 * EventBus Service
 * %%
 * Copyright (C) 2012 AZAPTREE.COM
 * %%
 * 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.
 * #L%
 */

import java.lang.reflect.Method;
import java.util.concurrent.Executor;

import javax.annotation.PostConstruct;

import org.springframework.beans.factory.BeanNameAware;
import org.springframework.jmx.export.annotation.ManagedAttribute;
import org.springframework.jmx.export.annotation.ManagedResource;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.azaptree.services.eventbus.EventBusService;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.DeadEvent;
import com.google.common.eventbus.EventBus;
import com.google.common.eventbus.Subscribe;

/**
 * By default, the Spring bean name is used as the EventBus name.
 * 
 * Registers a DeadEvent event handler. Dead events are events that posted, but there are no registered subscribers for that
 * event type. When a DeadEvent is received, it logs a WARNING message.
 * 
 * @author Alfio Zappala
 * 
 */
@Service
@ManagedResource
public class EventBusServiceImpl implements EventBusService, BeanNameAware {

    private EventBus eventBus;
    private Executor executor;
    private String beanName;
    private String eventBusName;

    /**
     * Creates a synchronous EventBus, i.e., events are dispatched on the same thread.
     * 
     * The beanName is used as the EventBus identifier.
     */
    public EventBusServiceImpl() {
    }

    /**
     * Creates an <a href="http://docs.guava-libraries.googlecode.com/git-history/release/javadoc/index.html">AsyncEventBus</a>
     * 
     * @param executor
     */
    public EventBusServiceImpl(final Executor executor) {
        Assert.notNull(executor);
        this.executor = executor;
    }

    public EventBusServiceImpl(final String eventBusName) {
        init(eventBusName, null);
    }

    public EventBusServiceImpl(final String eventBusName, final Executor executor) {
        init(eventBusName, executor);
    }

    private void checkSubscribeMethodExists(final Object eventHandler) {
        for (final Method m : eventHandler.getClass().getMethods()) {
            if (m.getAnnotation(Subscribe.class) != null) {
                return;
            }
        }

        throw new IllegalArgumentException("eventHandler has no methods annotated with @Subscribe");
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.azaptree.services.eventbus.impl.EventBusServiceJmxApi#getEventBusName()
     */
    @Override
    @ManagedAttribute
    public String getEventBusName() {
        return eventBusName;
    }

    @PostConstruct
    public void init() {
        init(beanName, executor);
    }

    public void init(final String eventBusName, final Executor executor) {
        if (eventBus != null) {
            log.debug("eventBus has already been created");
            return;
        }

        Assert.hasText(eventBusName, "eventBusName is required");
        this.eventBusName = eventBusName;

        if (executor != null) {
            eventBus = new AsyncEventBus(eventBusName, executor);
        } else {
            eventBus = new EventBus(eventBusName);
        }

        eventBus.register(this);
        log.info("Created EventBus: {} -> {}", beanName, eventBus.getClass().getName());
    }

    /*
     * (non-Javadoc)
     * 
     * @see com.azaptree.services.eventbus.impl.EventBusServiceJmxApi#isAsynchronous()
     */
    @Override
    @ManagedAttribute
    public boolean isAsynchronous() {
        if (eventBus == null) {
            throw new IllegalStateException("EventBus has not yet been created");
        }
        return eventBus instanceof AsyncEventBus;
    }

    /**
     * Logs dead event as warnings. Dead events are events that posted, but there are no registered subscribers for that
     * event type.
     * 
     * @param deadEvent
     */
    @Subscribe
    public void logDeadEvent(final DeadEvent deadEvent) {
        final Object event = deadEvent.getEvent();
        log.warn("{} : DeadEvent : {} : {}", beanName, event.getClass().getName(), event);
    }

    @Override
    public void post(final Object event) {
        Assert.notNull(event, "event is required");
        eventBus.post(event);
    }

    @Override
    public void register(final Object eventHandler) {
        Assert.notNull(eventHandler, "eventHandler is required");
        checkSubscribeMethodExists(eventHandler);
        eventBus.register(eventHandler);
        log.info("{} : registered event handler: {} ", beanName, eventHandler.getClass().getName());
    }

    @Override
    public void setBeanName(final String name) {
        Assert.hasText(name);
        beanName = name;
    }

    @Override
    public void unregister(final Object eventHandler) {
        Assert.notNull(eventHandler, "eventHandler is required");
        eventBus.unregister(eventHandler);
        log.info("{} : unregistered event handler: {} ", beanName, eventHandler.getClass().getName());
    }
}