Thursday, May 6, 2010

Defining Data Models in a page and converting from BasePage

Tapestry 3 pages were defined as an extension of one of it's built in page classes, usually BasePage. These page classes are defined as "abstract" and Tapestry takes the abstract class you define and dynamically creates a subclass all fleshed out with standard properties and functionality at runtime.

Thus a typical page might be defined as follows:
public abstract class Checkout extends BasePage implements IExternalPage, PageRenderListener {

Now in tapestry 5 it would just be a simple class:
public class Checkout {

Note that there might be interface implementations or even class extensions used, but would be for special features required by the developer, and nothing directly to do with basic page functionality.

Data Models defined in Tapestry 3 page classes would also be abstract:
public abstract CustomerData getCustomerData();
public abstract void setCustomerData(CustomerData customerData);

public abstract OrderData getOrderData();
public abstract void setOrderData(OrderData orderData);

This would allow Tapestry to create the appropriate declarations in the subclass of your abstract page.

In Tapestry 5 adding the @Property annotation would cause the appropriate getter and setter to be generated:

@Persist(PersistenceConstants.FLASH)
@Property
private ShiptoData _shiptoData;

@Persist(PersistenceConstants.FLASH)
@Property
private DetailData _detailData;

For some reason I felt like these properties needed to be retained during the redirect that happens after every form submit (hence the FLASH). I still can't seem to get my head around this, when this is required and when it is taken care of automatically.

To be clear, this FLASH persistence is sometimes required, because when Tapestry 5 processes a form submit it always causes the browser to talk to the server twice. First it posts the submit, and the page class processes the data that is submitted from the form. The only reply that is made back to the browser is a "redirect" with the URL the browser should go to. The browser responds by making a request of the server to display the page at the URL it was redirected to.

In case of an error this redirected request will often be the same page with the form so the users can fix the problem with the information and resubmit the form. But that will be blank page like any other request might be starting with. Somehow tapestry, through the session data, must know which user's form data to display because that isn't necessarily contained in the redirect url.