user3663882
user3663882

Reputation: 7357

How to modify field values with AspectJ

I'm new to AOP with AspectJ and I need to write the following simple aspect:

I have the @EndDay:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface EndDay { }

annotation and I need to intercept all non-reflective assignation to all non-static fields of the type Date annotated with @EndDate annotation and then assign the value of the end of the day specified in the assigned Date object (e.g we're assigngn 2011-11-11 10:00:00, it's intercepted and assigned 2011-11-11 23:59:59 instead). What I have tried:

public aspect EndDay {
    before(): set(@DayEnd private Date *) {
        Date d = (Date) thisJoinPoint.getTarget();
        DateUtils.setDayEnd(d); //It an utility class modifying the date
    };
}

It didn't work properly. How can I fix that?

Upvotes: 2

Views: 2190

Answers (1)

user3663882
user3663882

Reputation: 7357

To change the value being assigned to a field we need to use the around advice, instead of before or after. The around advice specifies that we will perform some operations instead of ones being performed normally. Now, as the documentation says:

All set join points are treated as having one argument, the value the field is being set to, so at a set join point, that value can be accessed with an args pointcut.

That means we should have declared our advice for the conjucntion of the set(@DayEnd private Date *) and args(original). The first one picks out all the private fields assignments, but the second one specifying the value being assigned. Now, in order to assign the moified value we finally need to call proceed(_modified_argument).

The working aspect looks as follows:

public aspect DayBoundaries {

   void around(Date original): set(@DayEnd private Date *) && args(original){
        Calendar c = Calendar.getInstance();
        c.setTime(original);
        c.set(Calendar.HOUR_OF_DAY, 23);
        c.set(Calendar.MINUTE, 59);
        c.set(Calendar.SECOND, 59);
        c.set(Calendar.MILLISECOND, 999);
        proceed(c.getTime());
    };
}

Upvotes: 2

Related Questions