With my aspect, I track the changes on certain collections by advising certain method calls on instances of java.util.Set
, notably add(Object)
and remove(Object)
. Since the changes are not reflected in the collection itself, invocations of Set.contains(Object)
or Set.size()
return wrong results.
Therefore I want to intercept all method calls to instances of Set (except add
and remove
), and forward the calls to my up-to-date collection.
Of course I could define two advices, using different pointcuts, something like this:
// matches Collection.size(), Collection.isEmpty(), ...
* around(Collection c) : call(* Collection.*()) && target(c)
&& !remove(/*...*/) && !add(/*...*/) {
if (notApplicable())
return proceed(c);
return proceed(getUpToDateCollection());
}
// matches Collection.contains(Object), ...
* around(Collection c, Object arg) : call(* Collection.*(*)) && target(c) && args(arg)
&& !remove(/*...*/) && !add(/*...*/) {
if (notApplicable())
return proceed(c, arg);
return proceed(getUpToDateCollection(), arg);
}
It works, but it's pretty ugly, the bodies of my advices being quite analogous. So I would like to "combine" them; effectively having a single advice that be woven for both pointcuts, much like this:
* around(Object[] args): call(* Collection.*(..)) && args(arr) {...}`
Is this possible at all? I have the feeling it's not, because in one of the pointcuts I expose the argument (and subsequently use it in the advice) and in the other there is no argument, so it seems impossible to bind the "potential identifier" in the enclosing advice... But I'm hoping that I've overlooked something and you might be able to point me in the right direction. Thanks!