Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-dev] Extended perobjects association proposal

 
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

So, I have done some homework and written down a small proposal
employing the use case from the "association aspects" paper (Bit and
Equality):

######################################
First the Equality relation:
######################################

public aspect Equality perobjects {

    private String label;
    
    private Bit[] bits;
    
    /* constructors cannot be called explicitly; they are called by
     * enableFor(...) (see use case) */
    public Equality(Bit... bits) {        
        this(bits, null);
    }
        
    /* constructors cannot be called explicitly; they are called by
     * enableFor(...) (see use case) */
    public Equality(Bit... bits, String label) {
        /* the following check should maybe be done by the backing
         * implementation implicitly for all arguments passed to
associate
         * to not allow association with null */
        for(Bit b: bits) {            
            if(b==null)
                throw new IllegalArgumentException("argument null");
        }
        /* associate the state of the new aspect instants with "bits"
         * use type inference to statically gain type inforation for
         * the backing implementation;
         * association *must* happen on all paths through each
         * constructor! */
        associate(bits);
        this.label = label;
        this.bits = bits;
    }

    public String getLabel() {        
        return label;
    }

    /*
     * code implementing equality as in "association aspects" paper.
     */
    
    /* example advice instantiating new perobject aspects */
    after(Bit b1, Bit b2): call(@NeedsEquality * *.*(Bit,Bit)) &&
args(b1,b2) {
        /* establish equality */
        Equality.enableFor(b1,b2);
        /* "associate" must not be called here (neither in any piece
of advice */
    }
    
    /* implicitly delared by the AJ backend:
     * 
     * public static void enableFor(Bit... bits, String label)
     * public static void enableFor(Bit... bits)
     * public static void disableFor(Bit... bits, String label)
     * public static void disableFor(Bit... bits)
     *
     * public static void associated(Bit... bits) // signature
inferred from call to associate above
     */
}

###########################
Remarks:
###########################
- - We note, that objects passed to "associate" should be checked for
non-nullness by the AJ backend.
- - It must be checked for each constructor, that "associate" is called
on any possible path.
- - The constructor should not explicitly be callable from the outside.
(enableFor is used instead)
- - The compiler generates static methods enableFor/disableFor for each
constructor signature. (maybe a single one with varargs may suffice,
too)
- - The compiler generates an "associated" method, which matches all
possibly inferred types which are passed to "associate". (maybe again
varargs suffice entirely)
- - On calling enableFor(..) the first time with non-null arguments, an
aspect instance is instantiated and the arguments are associated
using (weak) hashmaps or similar, previously being generated by the
AJ compiler.
- - On disableFor(..) the argument objects are removed from the
association. It should be made sure that the aspect instance may be
GCed when all associations are gone.

##########################
A possible consumer class
##########################

public class EqualityConsumer {

    public static void main(String[] args) {
        Bit b1, b2, b3;
        
        /* this will call the appropriate Equality constructor
implicitly
         * to associate b1 and b2 resp. b1 and b3 */
        Equality.enableFor(b1,b2,"Those should be equal because...");
      
        Equality.enableFor(b1,b3,"Those should be equal because...");
      
        
        /* check if b1, b2 are associated; (b1,b2) is an *ordered*
list */
        if(Equality.associated(b1,b2)) {            
            System.out.print("b1 and b2 are assured to be equal.
Reason: ");
            /* access aspect instance for b1, b2; (b1,b2) is an
*ordered* list */
            System.out.println(Equality.aspectOf(b1,b2).getLabel());
        } else {
            throw new RuntimeException("b1, b2 should be
associated");
        }
        
        /* disable association of b1 and b2 */
        Equality.disableFor(b1,b2);       
        if(Equality.associated(b1,b2)) {
            throw new RuntimeException("b1, b2 should not be
associated");
        }

        /* disable association of b1 and b2 */
        Equality.enableFor(b1,b2);       
        if(!Equality.associated(b1,b2)) {
            throw new RuntimeException("b1, b2 should be
associated");
        }
        
        Equality.disableFor(b1,b2);
        Equality.disableFor(b1,b3);
        
        /* all associated objects are disabled; make sure the aspect
         * instance can begarbage collected by using weak links */
    }
}

#######################

As Wes pointed out earlier, perthis and so forth could very likely be
simulated by this approach.
One problem is here the lacking possibility to override a piece of
advice. It would be great if a perobject aspect could just have a
piece of advice telling when to create instances of itself and if
then subclasses could override or extend this instantiation model.
Unfortunately, since an advice cannot be overridden, this may be
infeasible at the moment.

So what do people think?

Eric

-----BEGIN PGP SIGNATURE-----
Version: PGP 8.0.3

iQA/AwUBQfuWPswiFCm7RlWCEQLFggCcDRgWxqS5xaHMIKSIWmJ/NJbIiPIAnAlk
lA/C+HX9JdYLMd3ylkw4rqip
=SnIy
-----END PGP SIGNATURE-----




Back to the top