| home / programming / tapestry / 1 | [previous] |
|
|
The _user
instance variable stores the Person data object for the logged-in
user. Because the field is transient, its value may be lost at any time due
to clustering.
Whenever the _user
variable is null, it can be reacquired from the engine (using the VirtualLibraryEngine
subclass).
The Visit object is stored in the HttpSession as a session attribute after
most requests. On any request where the Visit object is accessed, the framework
makes the assumption that the Visit has been changed.1 This triggers the Tapestry
ApplicationServlet to store the engine (and with it, the Visit) in the HttpSession
at the end of the request, after the response page has been sent back to the
client.
In a nonclustered environment, this has little impact because the HttpSession
is just a glorified java.util.Map; storing attributes in the session
doesn’t trigger any additional behavior. In a clustered environment, the
engine and, with it, the Visit may be serialized and copied to
a backup server within the cluster. It’s in the best interests of general
application performance for the Visit object to serialize efficiently.2
1 Since the engine doesn’t know anything about the Visit,
it is forced to assume that any access of the Visit is a potential
change to the Visit that must be propagated throughout the application server
cluster.
The Visit object declares a static serialVersionUID
constant. Declaring this as a static variable means that the JVM does not have
to compute this value at runtime, leading to a modest efficiency improvement.
A better improvement is to implement the java.io.Externalizable
interface (instead of the java.io. Serializable interface). This
allows you to write more efficient methods to save and restore the state of
the object. This is an example of where runtime performance profiling would
be used: to see just how much time is being spent serializing the Visit
object. Based on that data, a decision about the merits of expending effort
on serialization of the Visit can be made.
The Visit object tracks the logged-in user’s ID, but also
the Person object representing the user. The latter is the value
object for the Person entity and is needed in the presentation
layer to display the user’s name or to determine the user’s administrative
privilege. These user ID and Person instances are stored in two
separate instance variables. The user’s ID is stored persistently, but
the Person object is stored transiently. This means that the Person
object, within the Visit, does not have to be serialized
when the Visit is itself serialized, an obvious optimization—but
only if the Person object can be restored when needed.
This on-demand restoration is handled in the getUser() method.
Rather than being a pure accessor method (taking no arguments), this method
requires that the IRequestCycle object be passed in. If the Person
object has been lost, this method can use the cycle to obtain the VirtualLibraryEngine
instance for the application, and use the engine to reread the Person.
You’ll be seeing this pattern in different guises repeatedly: store the minimum persistent state possible and recover the full state only as needed. The Tapestry framework provides the necessary structure for maintaining the minimal state and recovering the full state.
The inheritance hierarchy for pages is shown in figures 10.3 and 10.4. Figure 10.3 shows interfaces and base classes, and figure 10.4 shows how each page in the Virtual Library inherits from or extends from those interfaces and base classes.
At first glance there is an awfully large number of classes, but this is natural for a Tapestry application: Each page has its own class, even though in most
2 The engine implements the java.io.Externalizable interface for efficiency reasons.
Figure 10.3 The Virtual Library includes three interfaces (IActive, IErrorProperty, and IMessageProperty) and three base classes (ActivatePage, AdminPage, and Protected) from which the actual pages extend.
cases, the class is only a few lines long. The presentation layer accounts for approximately 1,850 lines of code, excluding comments. This is a surprisingly small number of lines, considering the amount of functionality present in the Virtual Library application. The application layer (the EJB implementations and value objects), at about 1,250 lines, is slightly smaller. Of course, a significant portion of the presentation layer is in non-Java artifacts: HTML templates, page specifications, and component specifications.
The Virtual Library includes base classes and interfaces that define additional logic. These classes and interfaces are primarily concerned with preventing unauthorized users from seeing pages, at least until they are authenticated. In addition, the Java classes for the ViewPerson and ViewBook pages implement the IExternal-Page interface. This is to allow links to persons and books to be stored as bookmarks. Table 10.2 lists the base classes and interfaces used by the application.
Table 10.2 Base classes and interfaces used to define and implement behavior common to many application pages

Now that we’ve established the general framework of the application,
we can start to drill down into the pages and components of the Virtual Library.
Figure 10.4 The 17 pages of the application extend from framework
base classes, such as BasePage, or from application-specific base
classes, such as ActivatePage.
| home / programming / tapestry / 1 | [previous] |
Created: March 27, 2003
Revised: May 8, 2004
URL: http://webreference.com/programming/tapestry/1