/** * Create a SourceFilteringListener for the given event source. * @param source the event source that this listener filters for, * only processing events from this source * @param delegate the delegate listener to invoke with event * from the specified source */ public SourceFilteringListener(Object source, ApplicationListener<?> delegate) { this.source = source; this.delegate = (delegate instanceof GenericApplicationListener ? (GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate)); }
private void supportsEventType( boolean match, Class<? extends ApplicationListener> listenerType, ResolvableType eventType) { ApplicationListener<?> listener = mock(listenerType); GenericApplicationListenerAdapter adapter = new GenericApplicationListenerAdapter(listener); assertEquals("Wrong match for event '" + eventType + "' on " + listenerType.getClass().getName(), match, adapter.supportsEventType(eventType)); }
/** * Create a new GenericApplicationListener for the given delegate. * @param delegate the delegate listener to be invoked */ @SuppressWarnings("unchecked") public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) { Assert.notNull(delegate, "Delegate listener must not be null"); this.delegate = (ApplicationListener<ApplicationEvent>) delegate; this.declaredEventType = resolveDeclaredEventType(this.delegate); }
@Test public void supportsSourceTypeWithSmartApplicationListener() { SmartApplicationListener smartListener = mock(SmartApplicationListener.class); GenericApplicationListenerAdapter listener = new GenericApplicationListenerAdapter(smartListener); listener.supportsSourceType(Object.class); verify(smartListener, times(1)).supportsSourceType(Object.class); }
@Override public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { return supportsEventType(ResolvableType.forClass(eventType)); }
/** * Broadcast {@link AlienEvent}s to child context {@link ApplicationListener} beans. */ private void onAlienEvent(AlienEvent e) { // Alien events are published to child contexts // we can't publish directly into child context because it will re-publish to it's parent causing potential listeners in the main context to receive the // event many times. ! for (Entry<String, GenericApplicationListenerAdapter[]> childListenersEntry : childApplicationListeners.entrySet()) { ApplicationContext ctx = childContexts.get(childListenersEntry.getKey()); if (ctx != null) { for (GenericApplicationListenerAdapter childListener : childListenersEntry.getValue()) { if (childListener.supportsEventType(e.getClass())) { childListener.onApplicationEvent(e); } } } } }
@Override public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { return supportsEventType(ResolvableType.forClass(eventType)); }
/** * Create a SourceFilteringListener for the given event source. * @param source the event source that this listener filters for, * only processing events from this source * @param delegate the delegate listener to invoke with event * from the specified source */ public SourceFilteringListener(Object source, ApplicationListener<?> delegate) { this.source = source; this.delegate = (delegate instanceof GenericApplicationListener ? (GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate)); }
@Test public void supportsEventTypeWithSmartApplicationListener() { SmartApplicationListener smartListener = mock(SmartApplicationListener.class); GenericApplicationListenerAdapter listener = new GenericApplicationListenerAdapter(smartListener); ResolvableType type = ResolvableType.forClass(ApplicationEvent.class); listener.supportsEventType(type); verify(smartListener, times(1)).supportsEventType(ApplicationEvent.class); }
@Override public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { return supportsEventType(ResolvableType.forClass(eventType)); }
/** * Create a new GenericApplicationListener for the given delegate. * @param delegate the delegate listener to be invoked */ @SuppressWarnings("unchecked") public GenericApplicationListenerAdapter(ApplicationListener<?> delegate) { Assert.notNull(delegate, "Delegate listener must not be null"); this.delegate = (ApplicationListener<ApplicationEvent>) delegate; this.declaredEventType = resolveDeclaredEventType(this.delegate); }
/** * Determine whether the given listener supports the given event. * <p>The default implementation detects the {@link SmartApplicationListener} * and {@link GenericApplicationListener} interfaces. In case of a standard * {@link ApplicationListener}, a {@link GenericApplicationListenerAdapter} * will be used to introspect the generically declared type of the target listener. * @param listener the target listener to check * @param eventType the event type to check against * @param sourceType the source type to check against * @return whether the given listener should be included in the candidates * for the given event type */ protected boolean supportsEvent( ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) { GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ? (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener)); return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType)); }
@Override @SuppressWarnings("unchecked") public boolean supportsEventType(ResolvableType eventType) { if (this.delegate instanceof SmartApplicationListener) { Class<? extends ApplicationEvent> eventClass = (Class<? extends ApplicationEvent>) eventType.resolve(); return (eventClass != null && ((SmartApplicationListener) this.delegate).supportsEventType(eventClass)); } else { return (this.declaredEventType == null || this.declaredEventType.isAssignableFrom(eventType)); } }
@Nullable private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) { ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass()); if (declaredEventType == null || declaredEventType.isAssignableFrom(ApplicationEvent.class)) { Class<?> targetClass = AopUtils.getTargetClass(listener); if (targetClass != listener.getClass()) { declaredEventType = resolveDeclaredEventType(targetClass); } } return declaredEventType; }
private void registerDelegateApplicationListener(H http, ApplicationListener<?> delegate) { ApplicationContext context = http.getSharedObject(ApplicationContext.class); if (context == null) { return; } if (context.getBeansOfType(DelegatingApplicationListener.class).isEmpty()) { return; } DelegatingApplicationListener delegating = context .getBean(DelegatingApplicationListener.class); SmartApplicationListener smartListener = new GenericApplicationListenerAdapter( delegate); delegating.addListener(smartListener); }
/** * Filter a listener early through checking its generically declared event * type before trying to instantiate it. * <p>If this method returns {@code true} for a given listener as a first pass, * the listener instance will get retrieved and fully evaluated through a * {@link #supportsEvent(ApplicationListener,ResolvableType, Class)} call afterwards. * @param listenerType the listener's type as determined by the BeanFactory * @param eventType the event type to check * @return whether the given listener should be included in the candidates * for the given event type */ protected boolean supportsEvent(Class<?> listenerType, ResolvableType eventType) { if (GenericApplicationListener.class.isAssignableFrom(listenerType) || SmartApplicationListener.class.isAssignableFrom(listenerType)) { return true; } ResolvableType declaredEventType = GenericApplicationListenerAdapter.resolveDeclaredEventType(listenerType); return (declaredEventType == null || declaredEventType.isAssignableFrom(eventType)); }
/** * Determine whether the given listener supports the given event. * <p>The default implementation detects the {@link SmartApplicationListener} * and {@link GenericApplicationListener} interfaces. In case of a standard * {@link ApplicationListener}, a {@link GenericApplicationListenerAdapter} * will be used to introspect the generically declared type of the target listener. * @param listener the target listener to check * @param eventType the event type to check against * @param sourceType the source type to check against * @return whether the given listener should be included in the candidates * for the given event type */ protected boolean supportsEvent( ApplicationListener<?> listener, ResolvableType eventType, @Nullable Class<?> sourceType) { GenericApplicationListener smartListener = (listener instanceof GenericApplicationListener ? (GenericApplicationListener) listener : new GenericApplicationListenerAdapter(listener)); return (smartListener.supportsEventType(eventType) && smartListener.supportsSourceType(sourceType)); }
@Nullable private static ResolvableType resolveDeclaredEventType(ApplicationListener<ApplicationEvent> listener) { ResolvableType declaredEventType = resolveDeclaredEventType(listener.getClass()); if (declaredEventType == null || declaredEventType.isAssignableFrom(ApplicationEvent.class)) { Class<?> targetClass = AopUtils.getTargetClass(listener); if (targetClass != listener.getClass()) { declaredEventType = resolveDeclaredEventType(targetClass); } } return declaredEventType; }
private void registerDelegateApplicationListener(H http, ApplicationListener<?> delegate) { ApplicationContext context = http.getSharedObject(ApplicationContext.class); if (context == null) { return; } if (context.getBeansOfType(DelegatingApplicationListener.class).isEmpty()) { return; } DelegatingApplicationListener delegating = context .getBean(DelegatingApplicationListener.class); SmartApplicationListener smartListener = new GenericApplicationListenerAdapter( delegate); delegating.addListener(smartListener); }
/** * Filter a listener early through checking its generically declared event * type before trying to instantiate it. * <p>If this method returns {@code true} for a given listener as a first pass, * the listener instance will get retrieved and fully evaluated through a * {@link #supportsEvent(ApplicationListener,ResolvableType, Class)} call afterwards. * @param listenerType the listener's type as determined by the BeanFactory * @param eventType the event type to check * @return whether the given listener should be included in the candidates * for the given event type */ protected boolean supportsEvent(Class<?> listenerType, ResolvableType eventType) { if (GenericApplicationListener.class.isAssignableFrom(listenerType) || SmartApplicationListener.class.isAssignableFrom(listenerType)) { return true; } ResolvableType declaredEventType = GenericApplicationListenerAdapter.resolveDeclaredEventType(listenerType); return (declaredEventType == null || declaredEventType.isAssignableFrom(eventType)); }