jdevelop
jdevelop

Reputation: 12296

Match argument with custom annotation on class - detect in runtime

I have annotation like @SecureObject, which might be applied to some classes. Additionally there is the ORM, which provides method like

public ObjectID get(Class paramClass, Object object);

Now I need to create aspect, which will be triggered only in case if paramClass is annotated with @SecureObject.

Straightforward solution like:

@Before("call(public * some.orm.Datastore.get(..,@SecureObject *,..))"
   void runBefore() {
     // method code
}

does not work - method is never invoked. but wired (checked with aspectj -debug).

Is it possible to achieve such behavior with AspectJ, and if so - how?

Upvotes: 0

Views: 302

Answers (1)

Domi
Domi

Reputation: 1749

The problem is that the first parameter of your get() method is of type Class.

Given that, you can't use an annotation-based method signature pattern. One possible solution is to use an if() pointcut expressions:

package aspects;

@Aspect
public class MyAspect {

    @Pointcut("if() && call(public * some.orm.Datastore.get(..)) && args(paramClass,..)")
    public static boolean runBefore(JoinPoint jp, Class paramClass) {
         return paramClass.isAnnotationPresent(annotation.SecureObject.class);
    }

    @Before("runBefore(jp, paramClass)")
    public void runBeforeAdvice(JoinPoint jp, Class paramClass) {
        System.out.println("annotated!");
    }
}

Note: This pointcut also triggers if no @SecureObject annotation is present but the if() condition gets evaluated at runtime.

Upvotes: 1

Related Questions