Summary
Definitions
Overview
Illustration 1
Page Template
-Page Specification
Page Class
Application Specification
web.xml
Illustration 2
Illustration 3
The Framework - a flyby
Conclusion
Biography
Resources
|
Page Specification
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE page-specification PUBLIC
"-//Apache Software Foundation//Tapestry Specification 3.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
<page-specification class="demo.Home">
<component id="user" type="Insert">
<binding name="value" expression="userName"/>
</component>
<context-asset name="$template" path="Home.html"/>
</page-specification>
Listing 2. Home.page
The specification is the part that drives a component and ties its
pieces together. It specifies, among a lot of things, the class that
defines the behavior of the component under construction (called
container or parent component – Home Page in our example), the
template for the container component and the components to be plugged
in place of the template's placeholder tags (called contained or
child components). The defining class (also known as component class
– demo.Home in our example) of the container
component is specified using the class attribute of the
specification root element – page-specification .
The container component's template is specified using the
context-asset element. A component can have any number of types
of assets (images, stylesheets etc.) associated with it and the
template is treated as one such type. The template asset is specified
using the special name $template . The contained components
are declared using the component element. Components thus
declared are known as an "Explicit" or "Declared"
components. The id attribute of the component
element is like an Object reference in OO paradigm, and is the same as
the jwcid attribute of the placeholder tag in the
template. Thus the framework knows which component needs to be plugged
into which placeholder tag. The type of component to be instantiated
and plugged in is defined by the type attribute of the
component tag. The component we use in our example is the
Insert JWC that comes with Tapestry's core library.
As mentioned before, every component serves a specific purpose and so
is our Insert JWC. The Insert JWC, like the
name suggests, inserts text (the user name in our example) in place of
the placeholder tag in the template. The text to be inserted is
provided to the JWC via a parameter defined by the component.
Parameters are the gateway to configure components in Tapestry.
Component parameters are like method parameters, the difference being
that component parameters can be two-way; i.e., component parameters
can pass in a value and also spit out a value. Tapestry allows four
different kinds of parameters - in, form, custom and
auto . in parameters can only pass in a value
to the component, while the other kinds can pass values in and out of a
component. The value passed in to a component is stored in the JWC as a
JavaBeans property (known as parameter-property) in the component
class. The value passed out of a component is updated in the variable
that was the source of the data that was passed in. This variable is
usually an attribute of the container component class, although it can
be any variable accessible from the container component class. In
addition to the parameter property, the JWC houses another JavaBeans
property called the binding-property. Every JWC parameter-property is
accompanied by a binding-property. The name of the binding-property is
the name of the parameter-property + the literal suffix
Binding . The purpose of the binding-property, like the name
suggests, is to bind a foreign object (unknown at the time of component
definition) to the JWC parameter-property. This allows a JWC to be
decoupled from the source of data for the parameter-property. This
decoupling is achieved with the help of another incredible open source
project – Object Graph Navigation Library, OGNL. The component
class will use the parameter-property, via the JavaBeans-style
get method, as needed in defining the component's behavior.
The get<ParameterProperty> method in turn, will use
the get<ParameterProperty>Binding method, which
will retrieve the bound object at runtime, using OGNL, and make it
available to the component class as shown in Figure 2. The
parameter-property is specified in the JWC specification at the time of
component definition and the binding-property is automatically created
and provided by the framework at runtime. The actual binding of the
foreign object, though, is specified at the time of component
declaration in the container component's specification as shown in
our Page specification (Listing 2).
Figure 2. Parameter mechanics
The binding is specified in the component declaration using the
binding element, nested within the component
element. The binding element has two attributes –
name and expression . Attribute
name specifies the name of the parameter and the
expression attribute specifies the foreign object to bind. The
foreign object is any object that can be accessed from within the
container component class via a JavaBeans-style get
method, or an object that is the result of an OGNL expression. The
target foreign object can be a very distant object in the object graph
and yet be accessed from right within the expression
attribute. This object graph navigation is achieved via OGNL. Please
see Resources for information on OGNL
expressions.
The Insert JWC (user in our example) defines
a parameter called value . This parameter is bound to the
foreign object (userName in our example) via the
binding element as shown in the example Page specification
(Home.page ). At runtime, the user instance
JWC reads the value of userName attribute of
demo.Home instance and updates the value parameter
using OGNL. The user instance then uses the parameter
value and inserts it into the template.
Page components are special JWCs, as already stated. Page components
are root level components (can never be contained components) with
special attributes and responsibilities. Page components cannot be used
as building blocks to compose other components; that said, parameters
are useless in Page components and so the framework forbids Pages from
having parameters.
The naming convention for specifications is the name of the component
with an extension of .page (for Page components) or
.jwc (for non-Page components). And thus the specification for
our Page component is named Home.page . Specifications are
typically placed under the WEB-INF folder of the
application context. So, if Welcome is the context of our
Welcome application, Home.page will typically be placed
under webapps/Welcome/WEB-INF .
|