For each method where the @AppliesTo annotated Concern is evaluated, the AppliesToFilter will be checked to see whether the Concern method should be added to the Invocation Stack. If the @AppliesTo annotation has an annotation, then the Qi4j runtime will use a built-in filter to see if the method is annotated with such annotation.
The @AppliesTo is evaluated during the boot-strapping phase, which means that it is not possible to evaluate the AppliesToFilter during the runtime invocation of the method, but that also means that there is very little runtime overhead.
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.TYPE, ElementType.METHOD } )
@Documented
public @interface AppliesTo
{
// List of interfaces, annotations or AppliesToFilter
// implementation classes.
// If one of them matches the current element it will be accepted,
// so this list can be considered an "or"
Class[] value();
}
@Retention( RetentionPolicy.RUNTIME )
@Target( { ElementType.METHOD } )
@Documented
@InjectionScope
public @interface Funky
{}
@Concerns( FunkConcern.class )
public interface MySpecialComposite extends Composite, MySpecial
{}
public interface MySpecial
{
void notFunkyMethod();
@Funky void thisIsFunkyMethod();
}
public class FunkyFilter
implements AppliesToFilter
{
public boolean appliesTo(
Method method, Class mixinType,
Class compositeType, Class concernClass )
{
String methodName = method.getName();
return methodName.contains( "Funky" ) &&
!methodName.contains( "notFunky" );
}
}
@Concerns( FunkConcern.class )
public interface MySpecialComposite extends Composite, MySpecial
{}
public interface MySpecial
{
void notFunkyMethod();
void thisIsFunkyMethod();
String ordinaryMethod();
}