001/* 002 * Copyright 2002-2015 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.context.event; 018 019import org.springframework.context.ApplicationEvent; 020import org.springframework.context.ApplicationListener; 021import org.springframework.core.Ordered; 022import org.springframework.core.ResolvableType; 023 024/** 025 * {@link org.springframework.context.ApplicationListener} decorator that filters 026 * events from a specified event source, invoking its delegate listener for 027 * matching {@link org.springframework.context.ApplicationEvent} objects only. 028 * 029 * <p>Can also be used as base class, overriding the {@link #onApplicationEventInternal} 030 * method instead of specifying a delegate listener. 031 * 032 * @author Juergen Hoeller 033 * @author Stephane Nicoll 034 * @since 2.0.5 035 */ 036public class SourceFilteringListener implements GenericApplicationListener, SmartApplicationListener { 037 038 private final Object source; 039 040 private GenericApplicationListener delegate; 041 042 043 /** 044 * Create a SourceFilteringListener for the given event source. 045 * @param source the event source that this listener filters for, 046 * only processing events from this source 047 * @param delegate the delegate listener to invoke with event 048 * from the specified source 049 */ 050 public SourceFilteringListener(Object source, ApplicationListener<?> delegate) { 051 this.source = source; 052 this.delegate = (delegate instanceof GenericApplicationListener ? 053 (GenericApplicationListener) delegate : new GenericApplicationListenerAdapter(delegate)); 054 } 055 056 /** 057 * Create a SourceFilteringListener for the given event source, 058 * expecting subclasses to override the {@link #onApplicationEventInternal} 059 * method (instead of specifying a delegate listener). 060 * @param source the event source that this listener filters for, 061 * only processing events from this source 062 */ 063 protected SourceFilteringListener(Object source) { 064 this.source = source; 065 } 066 067 068 @Override 069 public void onApplicationEvent(ApplicationEvent event) { 070 if (event.getSource() == this.source) { 071 onApplicationEventInternal(event); 072 } 073 } 074 075 @Override 076 public boolean supportsEventType(ResolvableType eventType) { 077 return (this.delegate == null || this.delegate.supportsEventType(eventType)); 078 } 079 080 @Override 081 public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) { 082 return supportsEventType(ResolvableType.forType(eventType)); 083 } 084 085 @Override 086 public boolean supportsSourceType(Class<?> sourceType) { 087 return (sourceType != null && sourceType.isInstance(this.source)); 088 } 089 090 @Override 091 public int getOrder() { 092 return (this.delegate != null ? this.delegate.getOrder() : Ordered.LOWEST_PRECEDENCE); 093 } 094 095 096 /** 097 * Actually process the event, after having filtered according to the 098 * desired event source already. 099 * <p>The default implementation invokes the specified delegate, if any. 100 * @param event the event to process (matching the specified source) 101 */ 102 protected void onApplicationEventInternal(ApplicationEvent event) { 103 if (this.delegate == null) { 104 throw new IllegalStateException( 105 "Must specify a delegate object or override the onApplicationEventInternal method"); 106 } 107 this.delegate.onApplicationEvent(event); 108 } 109 110}