Tapestry Training -- From The Source

Let me help you get your team up to speed in Tapestry ... fast. Visit howardlewisship.com for details on training, mentoring and support!

Wednesday, June 15, 2005

Annotations + Bytecode Generation == Mixins

I'm beginning to use the new Tapestry annotations as part of my current paying gig and I'm very much liking what I see. Starting from the basic Tapestry assumption that classes are abstract and need to be extended at runtime to be concrete actually opens up a goodly number of new techniques.

For example, I have a series of pages that all help edit a large shared object, a RegistrationData instance, stored as an application state object.

Before annotations, I would have had to duplicate the following on each page's specification and Java source:

  <inject property="data" type="state" object="registration-data"/>

  public abstract RegistrationData getData();

But with annotations, the XML part goes away:

  public abstract RegistrationData getData();

But does even this have to be inside my page class? I have a number of pages that all need the same injected state object, so I can put this into an interface:

public interface RegistrationWizardPage {

  RegistrationData getData();

Now we're on to something; each page extends this interface (but is still abstract) and, in effect, this interface is acting as a mixin. Implementing the interface adds the abstract getData() method and annotation and, thanks to Tapestry's runtime bytecode enhancements, the implementation of getData().

In the past, I've talked about getting away from abstract classes in Tapestry. Now I'm not so sure; the combination of abstract classes and annotations seems awfully potent.

Side note: the Tapestry test suite is well over 1200 individual tests now.


erocha said...

How would it be without abstract classes? Simple getters/setters with private fields? In this case, using a base classe with the annotation and the pages extending it wouldn't be the same as with the interface? Of course we could not subclass more than one class, as we could with interfaces. By the way, I am new to Tapestry and I think that "AbstractInstantiator" is good enough for unit testing page classes, even if integration test for page+specification+template is not so easy. I am eager to see how this will be done in Tapestry 4.

verbat said...

sorry about reviving this old message.. but had'nt you written a paper about mixins in java some time ago?
I can't find it, thought I remember it was cool stuff.