001: /*
002: * Copyright 2002-2006 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: * http://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:
017: package org.springframework.context.event;
018:
019: import java.lang.reflect.Constructor;
020:
021: import org.aopalliance.intercept.MethodInterceptor;
022: import org.aopalliance.intercept.MethodInvocation;
023:
024: import org.springframework.beans.factory.InitializingBean;
025: import org.springframework.context.ApplicationEvent;
026: import org.springframework.context.ApplicationEventPublisher;
027: import org.springframework.context.ApplicationEventPublisherAware;
028:
029: /**
030: * {@link MethodInterceptor Interceptor} that publishes an
031: * <code>ApplicationEvent</code> to all <code>ApplicationListeners</code>
032: * registered with an <code>ApplicationEventPublisher</code> after each
033: * <i>successful</i> method invocation.
034: *
035: * <p>Note that this interceptor is only capable of publishing <i>stateless</i>
036: * events configured via the
037: * {@link #setApplicationEventClass "applicationEventClass"} property.
038: *
039: * @author Dmitriy Kopylenko
040: * @author Juergen Hoeller
041: * @author Rick Evans
042: * @see #setApplicationEventClass
043: * @see org.springframework.context.ApplicationEvent
044: * @see org.springframework.context.ApplicationListener
045: * @see org.springframework.context.ApplicationEventPublisher
046: * @see org.springframework.context.ApplicationContext
047: */
048: public class EventPublicationInterceptor implements MethodInterceptor,
049: ApplicationEventPublisherAware, InitializingBean {
050:
051: private Constructor applicationEventClassConstructor;
052:
053: private ApplicationEventPublisher applicationEventPublisher;
054:
055: /**
056: * Set the application event class to publish.
057: * <p>The event class <b>must</b> have a constructor with a single
058: * <code>Object</code> argument for the event source. The interceptor
059: * will pass in the invoked object.
060: * @throws IllegalArgumentException if the supplied <code>Class</code> is
061: * <code>null</code> or if it is not an <code>ApplicationEvent</code> subclass or
062: * if it does not expose a constructor that takes a single <code>Object</code> argument
063: */
064: public void setApplicationEventClass(Class applicationEventClass) {
065: if (ApplicationEvent.class.equals(applicationEventClass)
066: || !ApplicationEvent.class
067: .isAssignableFrom(applicationEventClass)) {
068: throw new IllegalArgumentException(
069: "applicationEventClass needs to extend ApplicationEvent");
070: }
071: try {
072: this .applicationEventClassConstructor = applicationEventClass
073: .getConstructor(new Class[] { Object.class });
074: } catch (NoSuchMethodException ex) {
075: throw new IllegalArgumentException(
076: "applicationEventClass ["
077: + applicationEventClass.getName()
078: + "] does not have the required Object constructor: "
079: + ex);
080: }
081: }
082:
083: public void setApplicationEventPublisher(
084: ApplicationEventPublisher applicationEventPublisher) {
085: this .applicationEventPublisher = applicationEventPublisher;
086: }
087:
088: public void afterPropertiesSet() throws Exception {
089: if (this .applicationEventClassConstructor == null) {
090: throw new IllegalArgumentException(
091: "applicationEventClass is required");
092: }
093: }
094:
095: public Object invoke(MethodInvocation invocation) throws Throwable {
096: Object retVal = invocation.proceed();
097:
098: ApplicationEvent event = (ApplicationEvent) this .applicationEventClassConstructor
099: .newInstance(new Object[] { invocation.getThis() });
100: this.applicationEventPublisher.publishEvent(event);
101:
102: return retVal;
103: }
104:
105: }
|