Kontakt

Meta-Programming with Tapestry

Posted on Freitag, 30th April, 2010

What’s exciting about Tapestry is the minimal amount of Java code needed to implement an application. Instead of writing tons of Java code you mark your classes with annotations and Tapestry does the rest for you. Tapestry sees these annotations on methods and fields and rebuilds your classes. This technique is called meta-programming and is described by Howard in this post.

An example of meta-programming with Tapestry is the @CommitAfter annotation. This annotation is provided by the Hibernate/Tapestry integration library and used to mark a service or a component method as transactional. Instead of committing a Hibernate Session inside a service method manually, you just mark the method with this annotation. Tapestry will invoke the method and commit the active transaction for you.

public interface UserDAO {
    @CommitAfter
    void add(User user);

    List<User> findAll();

    @CommitAfter
    void delete(User... users);

    @CommitAfter
    void deleteAll();
}

Another example is the @Log annotation which may be placed on component methods. In the following example Tapestry will log for the annotated method: method entry, method exit and any thrown exception at debug level.

public class MyComponent {

    @Log
    Object onAction(EventContext context) {
       ...
    }
}

In the recent 5.2 snapshots you will find a new annotation, @DiscardAfter, which can be used to discard all persistent field changes for a page. Let’s create a simple Login page to see @DiscardAfter in action.

<html xmlns:t="http://tapestry.apache.org/schema/tapestry_5_1_0.xsd">
   <body>
      <t:form>
         Username:
         <t:textfield t:id="username" validate="required"/>

         Password:
         <t:passwordfield t:id="password" validate="required"/>

         <input type ="submit" value="Login"/>
      </t:form>
   </body>
</html>

When the form is submitted and validation is processed successfully, onSuccess() method is invoked. In this method you can login the user to your application. Note that we stored user’s input into a persistent storage (such as Session) by annotating the page properties with @Persist annotation. After a successful login we need to eliminate these values from the storage because they are not needed anymore. This is accomplished by invocation of ComponentResources#discardPersistentFieldChanges().

public class Login {
    @Property
    @Persist
    private String username;

    @Property
    @Persist
    private String password;

    @Inject
    private ComponentResources componentResources;

    void onSuccess() {
        // login the user here

        componentResources.discardPersistentFieldChanges();
    }
}

As of version 5.2 you don’t have to clear the state of the page manually. This task can be accomplished by meta-programming. Just annotate your method with @DiscardAfter and Tapestry will do the rest for you. Here is the modified Login page. Note that ComponentResources service can be removed from the page.

public class Login {
    @Property
    @Persist
    private String username;

    @Property
    @Persist
    private String password;

    @DiscardAfter
    void onSuccess() {
        // login the user here
    }
}

Now that you’ve learned meta-programming, you can imagine how productive you can be with Tapestry. In the future you can expect more meta-programming features that will reduce the amount of Java code to a minimum. Working with Tapestry will be even more fun.

 

avatar

Your name

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

 

Tapestry 5 Blog - Copyright © 2009 - Eclectic Theme by Your Inspiration Web - Powered by WordPress