@Override @SuppressWarnings("unchecked") public <E extends Event<?>> void route( Object key, E event, List<Registration<Object, ? extends BiConsumer<Object, ? extends Event<?>>>> consumers, Consumer<E> completionConsumer, Consumer<Throwable> errorConsumer) { if (null != consumers && !consumers.isEmpty()) { List<Registration<Object, ? extends BiConsumer<Object, ? extends Event<?>>>> regs = filter.filter(consumers, key); int size = regs.size(); // old-school for loop is much more efficient than using an iterator for (int i = 0; i < size; i++) { Registration<Object, ? extends BiConsumer<Object, ? extends Event<?>>> reg = regs.get(i); if (null == reg || reg.isCancelled() || reg.isPaused()) { continue; } try { ((BiConsumer<Object, E>) reg.getObject()).accept(key, event); } catch (Exceptions.CancelException cancel) { reg.cancel(); } catch (Throwable t) { if (null != errorConsumer) { errorConsumer.accept(Exceptions.addValueAsLastCause(t, event)); } else { logger.error("Event routing failed for {}: {}", reg.getObject(), t.getMessage(), t); if (RuntimeException.class.isInstance(t)) { throw (RuntimeException) t; } else { throw new IllegalStateException(t); } } } finally { if (reg.isCancelAfterUse()) { reg.cancel(); } } } } if (null != completionConsumer) { try { completionConsumer.accept(event); } catch (Throwable t) { if (null != errorConsumer) { errorConsumer.accept(Exceptions.addValueAsLastCause(t, event)); } else { logger.error("Completion Consumer {} failed: {}", completionConsumer, t.getMessage(), t); } } } }
/** * An {@link Router} that {@link Filter#filter filters} consumers before routing events to them. * * @author Andy Wilkinson * @author Stephane Maldini */ public class ConsumerFilteringRouter implements Router<Object, Event<?>> { private final Logger logger = Logger.getLogger(getClass()); private final Filter filter; /** * Creates a new {@code ConsumerFilteringEventRouter} that will use the {@code filter} to filter * consumers. * * @param filter The filter to use. Must not be {@code null}. * @throws IllegalArgumentException if {@code filter} or {@code consumerInvoker} is null. */ public ConsumerFilteringRouter(Filter filter) { Assert.notNull(filter, "filter must not be null"); this.filter = filter; } @Override @SuppressWarnings("unchecked") public <E extends Event<?>> void route( Object key, E event, List<Registration<Object, ? extends BiConsumer<Object, ? extends Event<?>>>> consumers, Consumer<E> completionConsumer, Consumer<Throwable> errorConsumer) { if (null != consumers && !consumers.isEmpty()) { List<Registration<Object, ? extends BiConsumer<Object, ? extends Event<?>>>> regs = filter.filter(consumers, key); int size = regs.size(); // old-school for loop is much more efficient than using an iterator for (int i = 0; i < size; i++) { Registration<Object, ? extends BiConsumer<Object, ? extends Event<?>>> reg = regs.get(i); if (null == reg || reg.isCancelled() || reg.isPaused()) { continue; } try { ((BiConsumer<Object, E>) reg.getObject()).accept(key, event); } catch (Exceptions.CancelException cancel) { reg.cancel(); } catch (Throwable t) { if (null != errorConsumer) { errorConsumer.accept(Exceptions.addValueAsLastCause(t, event)); } else { logger.error("Event routing failed for {}: {}", reg.getObject(), t.getMessage(), t); if (RuntimeException.class.isInstance(t)) { throw (RuntimeException) t; } else { throw new IllegalStateException(t); } } } finally { if (reg.isCancelAfterUse()) { reg.cancel(); } } } } if (null != completionConsumer) { try { completionConsumer.accept(event); } catch (Throwable t) { if (null != errorConsumer) { errorConsumer.accept(Exceptions.addValueAsLastCause(t, event)); } else { logger.error("Completion Consumer {} failed: {}", completionConsumer, t.getMessage(), t); } } } } /** * Returns the {@code Filter} being used * * @return The {@code Filter}. */ public Filter getFilter() { return filter; } }