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

com.google.common.eventbus.SubscriptionIntrospector Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
package com.google.common.eventbus;

import com.google.common.base.Preconditions;
import java.lang.reflect.Field;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

@SuppressWarnings({"UnstableApiUsage", "rawtypes"})
public class SubscriptionIntrospector {

  private static final String SUBSCRIBERS_FIELD = "subscribers";

  private final EventBus eventbus;
  private Map> subscribers;

  public SubscriptionIntrospector(final EventBus eventbus) {
    this.eventbus = eventbus;
  }

  public Set getListenedEvents() {
    return extractSubscribers().keySet();
  }

  public Set getSubscribers(final Class event) {
    final Set res = new HashSet<>();
    final Set subscribers = extractSubscribers().get(event);
    if (subscribers != null) {
      for (Subscriber subs : subscribers) {
        res.add(subs.target);
      }
    }
    return res;
  }

  public Set getSubscriberTypes(final Class event) {
    final Set res = new HashSet<>();
    for (Object obj : getSubscribers(event)) {
      res.add(extractType(obj));
    }
    return res;
  }

  @SuppressWarnings("unchecked")
  private Map> extractSubscribers() {
    synchronized (this) {
      if (subscribers == null) {
        try {
          final Field registryField = EventBus.class.getDeclaredField(SUBSCRIBERS_FIELD);
          registryField.setAccessible(true);
          final SubscriberRegistry registry = (SubscriberRegistry) registryField.get(eventbus);

          final Field subscribersField = SubscriberRegistry.class
              .getDeclaredField(SUBSCRIBERS_FIELD);
          subscribersField.setAccessible(true);

          subscribers = (Map>) Preconditions
              .checkNotNull(subscribersField.get(registry));
        } catch (Exception e) {
          throw new IllegalStateException("Failed to access subscribers collection", e);
        }
      }
      return subscribers;
    }
  }

  private Class extractType(final Object instance) {
    Class cls = instance.getClass();
    while (cls.getSuperclass() != Object.class) {
      if (!cls.getSimpleName().contains("$")) {
        break;
      }
      cls = cls.getSuperclass();
    }
    return cls;
  }
}