Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migration of unmigrated content due to installation of a new plugin
{
Div
Wiki Markup
style
float:right
titleRelated Articles
classaui-label
Content by Label
showLabelsfalse
showSpacefalse
titleRelated Articles
cqllabel = "new-users" and space = currentSpace()
|background=#eee} {contentbylabel:title=Related Articles|showLabels=false|showSpace=false|labels=new-users} {float}

Principle 1 – Static Structure, Dynamic Behavior

...

Tapestry is designed to be an agile working environment; "code less, deliver more". To support you writing less code Tapestry does a lot of work on your POJO pages and components when first loading them. It also uses shared instances of page and component classes (shared across multiple threads and requests). Having dynamically modifiable structure would imply that each request has its own instance and, further, that the entire structure would need to be serialized between requests so that it can be restored to handle later requests.

Tapestry also makes you more agile by speeding up the development cycle with Live Class Reloading. Tapestry monitors the file system for changes to Java page classes, component classes, service implementation classes, HTML templates and component property files, and it hot-swaps the changes into the running application without requiring a restart or losing session data. This provides a very short code-save-view cycle that no other framework can touch.

Scalability

When building large scale systems it is important to consider how your resources are going to be used on each deployed server, and how that information is going to be shared between servers. Static structure means that page instances do not need to be stored inside the HttpSession and simple browsing users do not require extra system resources. This lean use of the HttpSession is key to Tapestry's very high scalability, especially in a clustered configuration. Again, linking an instance of a page to a particular client would require vastly more server-side resources than having a single shared page instance.

...

In traditional Java frameworks (including Struts, JSF and even the now-ancient Tapestry 4) user code is expected to conform to the framework. You create classes that extend from framework-provided base classes, or implement framework-provided interfaces.

...

For example, you may have a login form and have a method that gets invoked when the form is submitted:

Code Block
langjava

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

  @Property
  private String password;

  @Component
  private Form form;

  @Inject
  private LoginAuthenticator authenticator;

  void onValidateFromForm()
  {
    if (! authenticator.isValidLogin(userId, password))
    {
      form.recordError("Invalid user name or password.");
    }
  }

  Object onSuccessFromForm()
  {
    return PostLogin.class;
  }
}

This short snippet demonstrates a bit about how Tapestry operates. Pages and services within the application are injected with the @Inject annotation. The method names, onValidateFromForm() and onSuccessFromForm(), inform Tapestry about when each method is to be invoked. This naming convention identifies the event that is handled, ("validate" and "success") and the id of the component from which the event is triggered (the "form" component FootnoteThe component id can be omitted, leaving the method name onSuccess(), but that may cause confusion on a page that has multiple Form components triggering events, so it's best to be specific about the source of the event.).

The "validate" event is triggered to perform cross-field validations, and the "success" event is only triggered when there are no validation errors. The onSuccessFromForm() method's return value directs Tapestry on what to do next: jump to another page within the application (here identified as the class for the page, but many other options exist). When there are exceptions, the page will be redisplayed to the user.

...

This is already evident in Tapestry 5.1, 5.2 and 5.3 where major new features and improvements have occurred, while remaining 100% backwards compatible to Tapestry 5.0 – as long as you've avoided the temptation to use internal APIs.

...

display-footnotes