Bus { public void register(Object object) { if (object == null) { throw new NullPointerException("Object to register must not be null."); } enforcer.enforce(this); Map<Class<?>, EventProducer> foundProducers = handlerFinder.findAllProducers(object); for (Class<?> type : foundProducers.keySet()) { final EventProducer producer = foundProducers.get(type); EventProducer previousProducer = producersByType.putIfAbsent(type, producer); if (previousProducer != null) { throw new IllegalArgumentException("Producer method for type " + type + " found on type " + producer.target.getClass() + ", but already registered by type " + previousProducer.target.getClass() + "."); } Set<EventHandler> handlers = handlersByType.get(type); if (handlers != null && !handlers.isEmpty()) { for (EventHandler handler : handlers) { dispatchProducerResultToHandler(handler, producer); } } } Map<Class<?>, Set<EventHandler>> foundHandlersMap = handlerFinder.findAllSubscribers(object); for (Class<?> type : foundHandlersMap.keySet()) { Set<EventHandler> handlers = handlersByType.get(type); if (handlers == null) { Set<EventHandler> handlersCreation = new CopyOnWriteArraySet<EventHandler>(); handlers = handlersByType.putIfAbsent(type, handlersCreation); if (handlers == null) { handlers = handlersCreation; } } final Set<EventHandler> foundHandlers = foundHandlersMap.get(type); if (!handlers.addAll(foundHandlers)) { throw new IllegalArgumentException("Object already registered."); } } for (Map.Entry<Class<?>, Set<EventHandler>> entry : foundHandlersMap.entrySet()) { Class<?> type = entry.getKey(); EventProducer producer = producersByType.get(type); if (producer != null && producer.isValid()) { Set<EventHandler> foundHandlers = entry.getValue(); for (EventHandler foundHandler : foundHandlers) { if (!producer.isValid()) { break; } if (foundHandler.isValid()) { dispatchProducerResultToHandler(foundHandler, producer); } } } } } Bus();  Bus(String identifier);  Bus(ThreadEnforcer enforcer);  Bus(ThreadEnforcer enforcer, String identifier);   Bus(ThreadEnforcer enforcer, String identifier, HandlerFinder handlerFinder); @Override String toString(); void register(Object object); void unregister(Object object); void post(Object event); static final String DEFAULT_IDENTIFIER; }
@Test public void registeringSameObjectTwiceFails() { StringCatcher catcher = new StringCatcher(); bus.register(catcher); try { bus.register(catcher); fail(); } catch (IllegalArgumentException e) { assertEquals("Object already registered.", e.getMessage()); } }
@Test public void producerCalledForExistingSubscribers() { StringCatcher catcher = new StringCatcher(); StringProducer producer = new StringProducer(); bus.register(catcher); bus.register(producer); assertEquals(Arrays.asList(StringProducer.VALUE), catcher.getEvents()); }
@Test public void subscribingOrProducingOnlyAllowedOnPublicMethods() { try { bus.register(new Object() { @Subscribe protected void method(Object o) {} }); fail(); } catch (IllegalArgumentException expected) { } try { bus.register(new Object() { @Subscribe void method(Object o) {} }); fail(); } catch (IllegalArgumentException expected) { } try { bus.register(new Object() { @Subscribe private void method(Object o) {} }); fail(); } catch (IllegalArgumentException expected) { } try { bus.register(new Object() { @Produce protected Object method() { return null; } }); fail(); } catch (IllegalArgumentException expected) { } try { bus.register(new Object() { @Produce Object method() { return null; } }); fail(); } catch (IllegalArgumentException expected) { } try { bus.register(new Object() { @Produce private Object method() { return null; } }); fail(); } catch (IllegalArgumentException expected) { } }
@Test(expected = IllegalArgumentException.class) public void voidProducerThrowsException() throws Exception { class VoidProducer { @Produce public void things() {} } bus.register(new VoidProducer()); }
@Test public void missingSubscribe() { bus.register(new Object()); }
@Test public void producingNullIsInvalid() { try { bus.register(new NullProducer()); } catch (IllegalStateException expected) { } }
@Test public void testExceptionThrowingProducer() throws Exception { bus.register(new ExceptionThrowingProducer()); try { bus.register(new DummySubscriber()); fail("Should have failed due to exception-throwing producer."); } catch (RuntimeException e) { } }