http://www.developer.com/

Back to article

Advanced Features of the Tapestry Framework


December 2, 2005

In the first part of this article, I discussed the main structure of the Tapestry framework, as well as its setup and configuration in an enterprise scale development environment such as JBuilder 2005. In this article, I will further explore the features of the framework and discuss specific components and pre-build modules. A sample application that uses Tapestry is included for your reference as well.

Structure of the Framework

As discussed in the first part of the article, the Tapestry framework tries to hide all of the plumbing associated with coding a Web application by giving developers a solid API set that feels more like a desktop Graphical User Interface (GUI) or a Swing development toolkit. For instance, it is never necessary to write code to directly read HTTP parameters, or directly deal with session, request, response, JSPs, tags, and so forth.

Most modern Web frameworks come with pre-build modules to help with development process, simplify specific functions, or give developers more flexibility. Tapestry is no exception; in fact, it excels in this area. It comes with a cornucopia of pre-built modules that have all of their functionality working "out of the box." I will elaborate on this later. In addition to providing a lot of APIs for the developer, Tapestry provides whole modules that try to do the most common tasks found in the Web application, such as file upload, date/calendar logic, table pagination, field validation, internalization, redirection, and even popup functionality. Among some of the more advanced modules that also come as standard functionality of Tapestry are data trees and charts.

At the time of this writing, Tapestry is at version 4. The class and interface hierarchy are fully developed and the code is stable. Most components also are finalized and production quality. The code for the framework is combined into several logical packages, each corresponding to a specific functionality or feature.

Here is a short list of the most interesting packages provided by the framework. The complete list is available in the references section as Appendix A.

org.apache.tapestry
org.apache.tapestry.components
org.apache.tapestry.contrib.jdbc
org.apache.tapestry.contrib.link
org.apache.tapestry.contrib.popup
org.apache.tapestry.contrib.table.model
org.apache.tapestry.contrib.tree.model
org.apache.tapestry.engine
org.apache.tapestry.event
org.apache.tapestry.form
org.apache.tapestry.html
org.apache.tapestry.listener
org.apache.tapestry.multipart
org.apache.tapestry.valid

The main packages are org.apache.tapestry and org.apache.tapestry.engine. They represent the "brains" of the framework and expose public interfaces, as well as concrete implementation of them for the developers. The IEngine AbstractEngine and BaseEngine interfaces are located there.

The org.apache.tapestry.components package has "Basic, fundamental components used to construct more complex components, or pages," are very powerful objects that allow a lot flexibility. The org.apache.tapestry.contrib.jdbc, org.apache.tapestry.multipart, and org.apache.tapestry.wml are some of the packages that contain a lot of extra useful functionality. I mention them to show just how massive the framework is, and how the creators are trying to cover all possible aspects of the enterprise Web development. The org.apache.tapestry.listener and org.apache.tapestry.event packages have some of the classes that give Tapestry APIs resemblance to the GUI or Swing listener mechanism for the pages (and objects on them). Because all of the logic of the Web interface is hidden in Tapestry, these classes make it very easy to code events and actions based on them.

The org.apache.tapestry.contrib.link and org.apache.tapestry.contrib.popup are helper packages that encapsulate links and popup windows. The org.apache.tapestry.form package encapsulates HTML forms and treats all of the HTML elements of the form as objects, giving developers ability to add listeners or associate state with these elements. The org.apache.tapestry.valid package has some useful validation classes, such as EmailValidator or DateValidator. There is a public interface IValidator, but it was very thoughtful of the Tapestry creators to include a lot of pre-built validator objects. The org.apache.tapestry.html package has components specific to the creation of HTML pages, including sophisticated DHTML JavaScript effects. If you are familiar with the Swing toolkit, you will find some likeness in the package structures, in particular org.apache.tapestry.contrib.table.model and org.apache.tapestry.contrib.tree.model have model classes for the tree and the table components. The GUI classes that use these models are in org.apache.tapestry.contrib.table.components and org.apache.tapestry.contrib.tree.components packages. These components are very robust and have pre–built-in functionality that performs without any extra work; for example, the table has sorting and pagination capabilities.

I recommend that you explore the great API documentation that comes with Tapestry before plunging in and coding some feature. Chances are if the feature is generic, it may available be already.

Framework Components

Because Tapestry encapsulates Web APIs in the form of a component object model, all of the most common Web objects are available as objects to developers. Here is the complete list of some of the components that are available "out of the box" with the Tapestry framework. You can also find more information about each of these at the official Tapestry Web page.

ActionLink DirectLink Image Radio Submit
Any ExceptionDisplay ImageSubmit RadioGroup TextArea
Block ExternalLink Insert RenderBlock TextField
Body FieldLabel InsertText RenderBody Upload
Button Foreach LinkSubmit Rollover ValidField
Checkbox Form ListEdit Script
Conditional Frame Option Select
DatePicker GenericLink PageLink ServiceLink
Delegator Hidden PropertySelection Shell

Contrib Library

Choose InspectorButton Palette TableFromPages TableValues
DateField MultiplePropertySelection PopupLink TableFormRows TableView
FormConditional NumericField Table TablePages ValidatingTextField
FormTable Otherwise TableColumns TableRows When

WML Library

Card Image Option Select Timer
Do Input Postfield SelectionField
Go OnEvent PropertySelection Setvar

High Level Interfaces and Data Flow

Developing in Tapestry requires not only using the provided components, learning the APIs, and XML component and page specification, but also understanding its main concepts and the logic flow of the framework.

There are several high-level concepts that developers need to know in order to use Tapestry successfully. One such conceptsis the Visit object. The Visit object holds information about a single client's visit to the Web page. This object is instantiated by the Engine and is maintained, serialized, and deserialized by it. This object can potentially be any custom object that implements a serializable interface and that is the only requirement; no other requirement is imposed. Under the hood, this object is stored persistently in the HttpSession.

To tell Tapestry framework which object it should use as a Visit object, the application specification file needs to have the "visit-class" property:

<b><property name="org.apache.tapestry.visit-class">
   com.myapp.Visit
</property>

In addition to the visit object concept, developers need to know some main interfaces such as IRequestCycle and IMarkupWriter. The IRequestCycle interface provides easy access to the controller object that manages a single request cycle. A request cycle is one 'hit' on the Web server. More importantly, it provides access to Tapestry's rendering pipeline and IEngineService object.

"A request cycle is broken up into two phases. The rewind phase is optional, as it is tied to ActionLink or Form components. In the rewind phase, a previous page render is redone (discarding output) until a specific component of the page is reached. This rewinding ensures that the page is restored to the exact state it had when the URL for the request cycle was generated, taking into account the dynamic nature of the page (Foreach, Conditional, etc.). Once this component is reached, it can notify its IActionListener. The listener has the ability to update the state of any pages and select a new result page."

The IMarkupWriter interface defines an object that can write markup (XML, HTML, or XHTML) style output. A IMarkupWriter handles translation from Unicode to the markup language as well as assisting with nested elements and closing tags.

IComponent represents a component that renders an HTML element on the page and IAsset represents an asset such as an image (GIF, JPEG, and so forth) that may be owned by an IComponent.

There are many more interfaces that are very useful in the Tapestry application, but they are beyond the scope of this article. You can look though API documentation to learn about the rest of them.

Exception Handling and Logging

Tapestry has an extremely sophisticated exception reporting and logging mechanism. The Exception reporting uses reflection to work backwards through the chain of exceptions, displaying JavaBeans properties of each exception and a stack trace of the deepest exception.

In addition, a wealth of detail about the servlet, application, request, servlet context, and JVM is displayed. The goal is to save developers debugging time by producing a complete report when exceptions do occur.

The look and feel of the exception reporting page can be customized per application.

Here is a snapshot of the wealth of output produced when an error occurs. This is only a small portion of the output from the JVM, and you can see the entire output included with the source code.

Generic Components and Features

As I mentioned, one of the great strengths of the Tapestry framework is its component-based architecture. It comes with many pre-built components; in addition, if you find that something is missing or need some custom component, all you need to do is write it and it will be reusable in other applications. To use any component, its XML specification needs to be added to the page specification file. For example, in addition to all the generic components ,such as, form, button, text field, and so on, Tapestry also has Request Forwarding, Field validation, Localization and Internalization, Calendar and Date, drop-down box, and any other extra components. Here is how you would add a drop-down box component to a page.

<page-specification class="com.somepackage.SomePage">
....
   <component id="dropDownBox" type="PropertySelection">
      <binding name="model" value="someValues"/>
      <binding name="value" value="valueId"/>
   </component>
</page-specification>

Or to use Calendar, you'd only need to add:

<component id="someDate" type="<b>DatePicker">
   <binding name="value" value="someDate"/>
</component>

Sample Project

The sample project builds upon the example from Part One and takes advantage of the some of the more advanced built-in features of the framework. Because Tapestry is a very advanced framework and offers a lot of pre-packaged functionality, the sample project will only show basic data flow. I will leave it up to the readers to explore the excellent API documentation provided with the framework (and also available online at http://jakarta.apache.org/tapestry/3.0.3/doc/api/index.html) to learn about the rest of the components.

I am assuming that you have set up the development environment as described in the first part and feel comfortable deploying Web applications on the application server. To run the application, unzip it into some directory and use the provided WAR file to deploy it on WebLogic.

Conclusion

In this article, I have covered some of the more advanced aspects of the Tapestry framework for Web development. I have expanded the sample project from the first part and built it into a real working application using some of the most popular and useful features of the framework.

Tapestry may not be for everyone because of its complexity and abundance of APIs, modules, and pre-packaged components. Its learning curve is definitely one of the longest comparing with the other frameworks, and its development style is fundamentally different from the other frameworks as well, but it certainly can be very rewarding if you put some time into it. If utilized properly, Tapestry can definitely shorten the development circle and reduce amount of coding in a Web application.

As a next step, I recommend looking at the online resources such as the Tapestry online tutorial and picking up any book about the framework.

Source Code

You can download the source code for this sample here. Compiling the sample requires Tapestry framework libraries. You can download those at http://jakarta.apache.org/site/downloads/downloads_tapestry.cgi. Extract them into the “lib” folder under the JBuilder project.

References

Online

Books

  • Art of Java Web Development: Struts, Tapestry, Commons, Velocity, JUnit, Axis, Cocoon, InternetBeans, WebWork (Paperback) by Neal Ford,ISBN: 1932394060

Appendix A: Compete Tapestry Package List

org.apache.tapestry
org.apache.tapestry.asset
org.apache.tapestry.bean
org.apache.tapestry.binding
org.apache.tapestry.callback
org.apache.tapestry.components
org.apache.tapestry.contrib.components
org.apache.tapestry.contrib.ejb
org.apache.tapestry.contrib.form
org.apache.tapestry.contrib.informal
org.apache.tapestry.contrib.inspector
org.apache.tapestry.contrib.jdbc
org.apache.tapestry.contrib.link
org.apache.tapestry.contrib.palette
org.apache.tapestry.contrib.popup
org.apache.tapestry.contrib.table.components
org.apache.tapestry.contrib.table.components.inserted
org.apache.tapestry.contrib.table.model
org.apache.tapestry.contrib.table.model.common
org.apache.tapestry.contrib.table.model.ognl
org.apache.tapestry.contrib.table.model.simple
org.apache.tapestry.contrib.table.model.sql
org.apache.tapestry.contrib.tree.components
org.apache.tapestry.contrib.tree.components.table
org.apache.tapestry.contrib.tree.model
org.apache.tapestry.contrib.tree.simple
org.apache.tapestry.contrib.valid
org.apache.tapestry.engine
org.apache.tapestry.enhance
org.apache.tapestry.enhance.javassist
org.apache.tapestry.event
org.apache.tapestry.form
org.apache.tapestry.html
org.apache.tapestry.jsp
org.apache.tapestry.link
org.apache.tapestry.listener
org.apache.tapestry.multipart
org.apache.tapestry.pageload
org.apache.tapestry.pages
org.apache.tapestry.param
org.apache.tapestry.parse
org.apache.tapestry.record
org.apache.tapestry.request
org.apache.tapestry.resolver
org.apache.tapestry.resource
org.apache.tapestry.script
org.apache.tapestry.spec
org.apache.tapestry.util
org.apache.tapestry.util.exception
org.apache.tapestry.util.io
org.apache.tapestry.util.pool
org.apache.tapestry.util.prop
org.apache.tapestry.util.xml
org.apache.tapestry.valid
org.apache.tapestry.wml
org.apache.tapestry.wml.pages

About the Author

Vlad Kofman is a Senior System Architect working on projects under government defense contracts. He also has been involved with enterprise-level projects for major Wall Street firms and the U.S. government. His main interests are object-oriented programming methodologies and design patterns.

Sitemap | Contact Us

Thanks for your registration, follow us on our social networks to keep up-to-date