The first thing you need to do is change
the implementation of setFamilyMembers() so that it clears the list and
adds all the new ones. Currently encapsulation is broken because you are
simply changing the reference to a List implementation which could be changed
by the call outside of the scope of Family. Then try the following aspect
to track changes to familyMembers:
import
java.util.List;
publicaspect
Aspect {
pointcut
addToList(Family family, List members, Person member):
call(boolean
List.add(*)) && this(family)
&& target(members)
&& args(member);
Object
around
(Family family, List members, Person member) : addToList(family, members,
member) {
boolean
changed = !members.contains(member);
Object ret = proceed(family,members,member);
if
(changed) fireChangeEvent(family,member);
return
ret;
}
Matthew Webster
AOSD Project
Java Technology Centre, MP146
IBM Hursley Park, Winchester, SO21 2JN, England
Telephone: +44 196 2816139 (external) 246139 (internal)
Email: Matthew Webster/UK/IBM @ IBMGB, matthew_webster@xxxxxxxxxx
http://w3.hursley.ibm.com/~websterm/
bjones@xxxxxxxxxxxxxxxxxxxx Sent by: aspectj-users-bounces@xxxxxxxxxxx
12/12/2006 15:17
Please respond to
aspectj-users@xxxxxxxxxxx
To
aspectj-users@xxxxxxxxxxx
cc
Subject
[aspectj-users] Domain model change
detection on a member of type java.util.List
I have what seems like a fairly basic question on
implementing a change
detection mechanism.
Suppose I have a Family type with a list of Persons:
public class Family {
private String familyName;
private List familyMembers = new ArrayList();
...
public void setFamilyMembers(List familyMembers) { this.familyMembers
=
familyMembers; }
public void addFamilyMember(Person familyMember) { this.familyMembers.add
(familyMember); }
...
}
How do a define a pointcut such that:
1) I can treat a 'set' to the entire familyMembers list similarly to an
'add'
to the list?
2) Within the related advice (assume around advice, if that matters), how
do I
get to the Family instance when the joinpoint is on the list.add method?!
I believe #2 is the tough part - but I think it's #2 that is truly important.
See, as part of the change detection I want to be able to look at the prev
and
new values and see if there really is a change. Then act on the fact
that
there is a change by registering the change somehow. This is of course
strightforward for any non list/collection type. But, in the case
of the
addFamilyMembers method (assuming I didn't want to control uniqueness within
the list) any call to this.familyMembers.add() should be considered a 'change'
to the Family type (i.e. a change to 'this'). However, I don't see
a way to
get the reference to the Family instance from the familyMembers.add joinpoint,
to register the change!
I'm aware of this mechanism to join on a call the List.add method, but
I don't
think it gives me exactly what I want (at least I don't think so):
pointcut addToList(): target(ArrayList) && call(* List.add(*))
The matching joinpoints (i.e. thisJoinPoint) only will expose the familyMembers
list, not the related Family instance that references the familyMembers
list.
Again, from this joinpoint, it's ultimately the 'parent' Family instance
that I
need, to register the change. It seem that I am in affect trying
to 'walk up'
the call stack one (or two?) frames to get to the family ('this') instance
within the call to this.familyMemebers.add()?!
What is the right pointcut (or set of pointcuts) to accomplish this?
Thanks!
Bryan
_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/aspectj-users