[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] Domain model change detection on a member of type java.util.List


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;

public aspect 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;
        private void fireChangeEvent (Object changed, Object change) {
                System.out.println("Aspect.fireChangeEvent() " + changed + " " + change);

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

Sent by: aspectj-users-bounces@xxxxxxxxxxx

12/12/2006 15:17

Please respond to

[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?


aspectj-users mailing list