Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Setting values for Annotations fields in runtime

In this particular example, it seems like you don't really need to change the annotation value itself. You just need to make sure you use either it's declared "permission" value or an override you read elsewhere. You could look for an updated value in the advice every time or cache it somehow.

For example, use an intertype declaration to insert an int field in the class annotated with MyAnnotation. Store the "mutable" value there instead:

public aspect CaptureAnnotationValueAspect {
    public static interface MyAnnoInterface {
        public int getPermission();
    }
    private int MyAnnoInterface.permission;
    public int  MyAnnoInterface.getPermission() { return permission; }
    public void MyAnnoInterface.setPermission(int p) { permission = p; }

    declare parents: (@MyAnnotation *) implements MyAnnoInterface;

    private int count = 0;
    void around(MyAnnotation myAnnotation, MyAnnoInterface myAnnoInterface):
        execution(* com.aspectprogramming.aspects.experiments.annos.*.*(..))
            && @annotation(myAnnotation) && target(myAnnoInterface) {
        myAnnoInterface.setPermission(myAnnotation.permission() + count);
        count++;
        System.out.println("Permission = "+myAnnoInterface.getPermission()+" in "+thisJoinPointStaticPart.toShortString());

        proceed(myAnnotation, myAnnoInterface);
    }
}

I declared an interface and used ITD to add it to any class that is annotated with MyAnnotation (which means that this example will only work if the annotation is on both the class and the method!). I also added a default permission field and accessor methods to the interface. (You could just make the new permission field public and skip the accessors....)

Note that you can't do something like

    private MyAnnotation.mutablePermission;

because this would attempt to inject the value on the annotation class itself, not the target class.

In the advice, I set the interface's permission value to the annotation's value, then for demonstration purposes, I added an incrementing count. Finally, the "println" statement uses the interface's permission, not the annotation's value.

If you change the test driver to call "a.foo()" several times, you'll see that the permission value counts up from -1.

Refinements would include moving the "MyAnnoInterface.setPermission()" call into advice on the constructor, since it only needs to happen once.

Hope this helps.
dean

Alexandru Popescu wrote:
#: Paulo Alexandre Corigo Zenida changed the world a bit at a time by saying on  1/4/2006 2:46 PM :#
Hello,

    I'm new to Annotations and I have previously searched for examples and tried some tests but I didn't achieve my goals, so I was wondering if someone could tell me: is it possible to change a value of an Annotation "field"?

    I was trying to create an Annotation that would tell me the access level required for a method to be executed, and I would like to set that access level by using properties declared in a properties file. To do so, I would like to change the default value for the Annotation in runtime. Is this possible?

    The source code would be something like this:

My Annotation:

    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.METHOD, ElementType.TYPE })
    public @interface MyAnnotation {
        int permission() default -1;
    }

Next, there's the class:

    import java.io.IOException;
    import java.util.Properties;

    @MyAnnotation(id = 3)
    public class A {

        @MyAnnotation
        public void foo() {

        }

        public static void main(String args[]) {
            A a = new A();
            a.foo();
        }
    }

And finally, here is the aspect:

    public aspect CaptureAnnotationValueAspect {

        void around(MyAnnotation myAnnotation):
            execution(* *.*(..)) && @annotation(myAnnotation) {

            System.out.println(myAnnotation.id());

            // How can I change the value for the Annotation, if possible?

            proceed(myAnnotation);
        }
    }


    Thanks in advance. Best regards,

        Paulo Zenida
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


afaik they are read-only (and I think i see a technical reason in this: they are written in the bytecode, so if changing the value, you should modify the bytecode).

hope i'm not wrong,

./alex
--
.w( the_mindstorm )p.

_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users


--
Dean Wampler's Signature
Dean Wampler, Ph.D.
dean at aspectprogramming.com
http://www.aspectprogramming.com
http://www.contract4j.org
I want my tombstone to say:
Unknown Application Error in Dean Wampler.exe.
Application Terminated.
 

Back to the top