Author: kentam Date: Thu Jan 13 16:36:04 2005 New Revision: 125125 URL: http://svn.apache.org/viewcvs?view=rev&rev=125125 Log: EventNotifiers generated in ControlBeans will allow interceptors to intercept an event before (preEvent) and after (postEvent) event listeners are notified of the event. Interceptors can stop notifications of an event to its listeners if its preEvent() method returns a "false" value.
Contributor: Hoi Lam Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java?view=diff&rev=125125&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java&r1=125124&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java&r2=125125 ============================================================================== --- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java (original) +++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/bean/ControlBean.java Thu Jan 13 16:36:04 2005 @@ -847,7 +847,7 @@ /** * Retrieves interceptor instances, creates them lazily. */ - private Interceptor ensureInterceptor( String n ) + protected Interceptor ensureInterceptor( String n ) { Interceptor i = _interceptors.get( n ); if ( i == null ) Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java?view=diff&rev=125125&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java&r1=125124&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java&r2=125125 ============================================================================== --- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java (original) +++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptMethod.java Thu Jan 13 16:36:04 2005 @@ -25,11 +25,15 @@ import java.util.Collections; import com.sun.mirror.apt.AnnotationProcessorEnvironment; +import com.sun.mirror.declaration.AnnotationMirror; +import com.sun.mirror.declaration.AnnotationTypeDeclaration; import com.sun.mirror.declaration.ClassDeclaration; import com.sun.mirror.declaration.MethodDeclaration; import com.sun.mirror.declaration.ParameterDeclaration; import com.sun.mirror.declaration.TypeParameterDeclaration; +import com.sun.mirror.type.AnnotationType; import com.sun.mirror.type.ClassType; +import com.sun.mirror.type.DeclaredType; import com.sun.mirror.type.PrimitiveType; import com.sun.mirror.type.ReferenceType; import com.sun.mirror.type.TypeMirror; @@ -82,6 +86,7 @@ { _methodDecl = methodDecl; _env = env; + _interceptorServiceNames = initInterceptorServiceNames(); } /** @@ -363,4 +368,76 @@ MethodDeclaration _methodDecl; int _index = -1; AnnotationProcessorEnvironment _env; + + /** + * Returns the names of interceptor service interfaces associated with this operation + * @return + */ + public Collection<String> getInterceptorServiceNames() + { + return _interceptorServiceNames; + } + + /** + * Returns the names of interceptor service interfaces associated with this operation, formatted as a + * constant initializer string. + * @return + */ + public String getInterceptorDecl() + { + Collection<String> names = getInterceptorServiceNames(); + if ( names == null || names.size() == 0 ) + return null; + + StringBuffer ret = new StringBuffer("{"); + + String [] n = names.toArray(new String[0]); + for (int i=0 ; i < n.length ; ++i) + { + ret.append('"'); ret.append( n[i] ); ret.append('"'); + if ( i != n.length-1 ) + ret.append(", "); + } + ret.append( "}" ); + + return ret.toString(); + } + + private Collection<String> initInterceptorServiceNames() + { + ArrayList<String> ret = new ArrayList<String>(); + + if (_methodDecl == null) + return ret; + + // Iterate over annotations on operation, looking for interceptor-based ones + Collection<AnnotationMirror> annotations = _methodDecl.getAnnotationMirrors(); + for ( AnnotationMirror a : annotations ) + { + AnnotationType at = a.getAnnotationType(); + AnnotationTypeDeclaration atd = at.getDeclaration(); + Collection<AnnotationMirror> metaAnnotations = atd.getAnnotationMirrors(); + + // Look for annotations that are meta-annotated with @InterceptorAnnotation + for ( AnnotationMirror ma : metaAnnotations ) + { + if ( ma.getAnnotationType().getDeclaration().getQualifiedName(). + equals( "org.apache.beehive.controls.spi.svc.InterceptorAnnotation" ) ) + { + // found an interceptor-based annotation, add it! + AptAnnotationHelper ia = new AptAnnotationHelper( ma ); + DeclaredType serviceType = (DeclaredType) ia.getObjectValue("service"); + String intf = serviceType.toString(); + ret.add( intf ); + + break; + } + } + } + + return ret; + } + + Collection<String> _interceptorServiceNames; + } Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java?view=diff&rev=125125&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java&r1=125124&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java&r2=125125 ============================================================================== --- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java (original) +++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/AptOperation.java Thu Jan 13 16:36:04 2005 @@ -44,42 +44,8 @@ _controlIntf = controlIntf; _operDecl = methodDecl; - _interceptorServiceNames = initInterceptorServiceNames(); } - /** - * Returns the names of interceptor service interfaces associated with this operation - * @return - */ - public Collection<String> getInterceptorServiceNames() - { - return _interceptorServiceNames; - } - - /** - * Returns the names of interceptor service interfaces associated with this operation, formatted as a - * constant initializer string. - * @return - */ - public String getInterceptorDecl() - { - Collection<String> names = getInterceptorServiceNames(); - if ( names == null || names.size() == 0 ) - return null; - - StringBuffer ret = new StringBuffer("{"); - - String [] n = names.toArray(new String[0]); - for (int i=0 ; i < n.length ; ++i) - { - ret.append('"'); ret.append( n[i] ); ret.append('"'); - if ( i != n.length-1 ) - ret.append(", "); - } - ret.append( "}" ); - - return ret.toString(); - } /** * Returns the name of the static field that holds the name of this method. @@ -96,48 +62,11 @@ return sb.toString(); } - /** * Returns the AptControlInterface associated with this ControlOperation */ public AptControlInterface getControlInterface() { return _controlIntf; } - private Collection<String> initInterceptorServiceNames() - { - ArrayList<String> ret = new ArrayList<String>(); - - if (_operDecl == null) - return ret; - - // Iterate over annotations on operation, looking for interceptor-based ones - Collection<AnnotationMirror> annotations = _operDecl.getAnnotationMirrors(); - for ( AnnotationMirror a : annotations ) - { - AnnotationType at = a.getAnnotationType(); - AnnotationTypeDeclaration atd = at.getDeclaration(); - Collection<AnnotationMirror> metaAnnotations = atd.getAnnotationMirrors(); - - // Look for annotations that are meta-annotated with @InterceptorAnnotation - for ( AnnotationMirror ma : metaAnnotations ) - { - if ( ma.getAnnotationType().getDeclaration().getQualifiedName(). - equals( "org.apache.beehive.controls.spi.svc.InterceptorAnnotation" ) ) - { - // found an interceptor-based annotation, add it! - AptAnnotationHelper ia = new AptAnnotationHelper( ma ); - DeclaredType serviceType = (DeclaredType) ia.getObjectValue("service"); - String intf = serviceType.toString(); - ret.add( intf ); - - break; - } - } - } - - return ret; - } - MethodDeclaration _operDecl; AptControlInterface _controlIntf; - Collection<String> _interceptorServiceNames; } Modified: incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm Url: http://svn.apache.org/viewcvs/incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm?view=diff&rev=125125&p1=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm&r1=125124&p2=incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm&r2=125125 ============================================================================== --- incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm (original) +++ incubator/beehive/trunk/controls/src/runtime/org/apache/beehive/controls/runtime/generator/ControlBean.vm Thu Jan 13 16:36:04 2005 @@ -346,17 +346,56 @@ return retval; #end #else + #if ($event.interceptorServiceNames.size() != 0) + Object [] argArray = new Object[] {$event.argList}; + if (!preEvent($event.methodField, argArray, ${event.methodField}Interceptors)) + return; + #end java.util.Iterator listenerIter = notifier.listenerIterator(); while (listenerIter.hasNext()) { $event.eventSet.formalShortName listener = ($eventSet.formalShortName)listenerIter.next(); listener.${event.name}($event.argList); } + #if ($event.interceptorServiceNames.size() != 0) + if (!postEvent($event.methodField, argArray, ${event.methodField}Interceptors)) + return; + #end #end } #end ## +## This macro defines the implementation of a preEvent method +## +#macro (declarePreEvent $eventSet) + private boolean preEvent(Method method, Object[] argArray, String[] interceptors) + { + for ( String n : interceptors ) + { + org.apache.beehive.controls.spi.svc.Interceptor i = ensureInterceptor( n ); + if (!i.preEvent( ${bean.shortName}.this, ${eventSet.formalShortName}.class , method, argArray )) + return false; + } + return true; + } +#end +## +## This macro defines the implementation of a preEvent method +## +#macro (declarePostEvent $eventSet) + private boolean postEvent(Method method, Object[] argArray, String[] interceptors) + { + for ( String n : interceptors ) + { + org.apache.beehive.controls.spi.svc.Interceptor i = ensureInterceptor( n ); + if (!i.postEvent( ${bean.shortName}.this, ${eventSet.formalShortName}.class , method, argArray )) + return false; + } + return true; + } +#end +## ## This macro defines an EventSet proxy implementation for routing events ## #macro (declareEventSetImpl $eventSet) @@ -368,8 +407,16 @@ extends $eventSet.notifierExtends implements ${eventSet.formalShortName}, java.io.Serializable { - #foreach ($eventMethod in $eventSet.events) - #declareEventImpl($eventMethod) + #set ( $interceptor = false ) + #foreach ($event in $eventSet.events) + #declareEventImpl($event) + #if ($event.interceptorServiceNames.size() != 0) + #set ( $interceptor = true ) + #end + #end + #if ( $interceptor ) + #declarePreEvent ($eventSet) + #declarePostEvent ($eventSet) #end } @@ -446,7 +493,16 @@ private static String[] _${operation.name}Interceptors = ${operation.interceptorDecl}; #end #end + + #foreach ($eventSet in $intf.eventSets) + #foreach ($event in $eventSet.events) + #if ($event.interceptorServiceNames.size() != 0) + private static String[] ${event.methodField}Interceptors = ${event.interceptorDecl}; + #end + #end + #end #end + ## ## This macro declares the code that prioritizes interceptor arrays for operations ## @@ -456,6 +512,14 @@ _${operation.name}Interceptors = org.apache.beehive.controls.runtime.bean.ControlBeanContext.prioritizeInterceptors( _${operation.name}Interceptors ); #end #end + #foreach ($eventSet in $intf.eventSets) + #foreach ($event in $eventSet.events) + #if ($event.interceptorServiceNames.size() != 0) + ${event.methodField}Interceptors = org.apache.beehive.controls.runtime.bean.ControlBeanContext.prioritizeInterceptors(${event.methodField}Interceptors); + #end + #end + #end + #end ## ## THE CONTROLBEAN CLASS TEMPLATE
