Apache Tapestry Components - Apache Tapestry

What is the use of Apache Tapestry Components?

Components and Pages are almost the same except that the Page is the root component and includes one or more child components. Components always reside inside a page and do almost all the dynamic functionality of the page. These components render a simple HTML links to complex grid functionality with interactive AJAX. Tapestry components consist of below items

  • Component Class − Component Class is the main Java class of the component.
  • XML Template − XML template is similar to Page template and the component class renders the template as the final output. Output will be generated by the component class itself using the MarkupWriter class when few components do not have templates.
  • Body − Component specified inside a page template can have a custom markup called “Component body”. If the component template has <body /> element, then <body /> element will be replaced by the body of the component.
  • Rendering − Rendering is a process which converts XML template and body of the component into actual output of the component.
  • Parameters − Parameters are used to create communication between component & pages to pass data between them.
  • Events − Events delegate functionality from components to its container / parent (pages or another component). It is widely used for page navigation purpose.

Rendering

Rendering a component is done in a series of pre-defined phases and each phase in the component system will have a corresponding method defined by convention or annotation in the component class.

Phases, its method name and its annotations are listed below.

Rendering

Each phase has a specific purpose and they are mentioned below

SetupRender

SetupRender kick-starts the rendering process and sets up parameters of the component.

BeginRender

BeginRender renders the component and renders begin / start tag of the component.

BeforeRenderTemplate

BeforeRenderTemplate is used to decorate the XML template by adding special markup around the template. It also provides an option to skip the template rendering.

BeforeRenderBody

BeforeRenderTemplate provides an option to skip the rendering of the component's body element.

AfterRenderBody

AfterRenderBody is called after the component's body is rendered.

AfterRenderTemplate

AfterRenderTemplate is called after the component's template is rendered.

AfterRender

AfterRender is the counterpart of the BeginRender and usually renders the close tag.

CleanupRender

CleanupRender is equivalent to SetupRender and releases / disposes all the objects created during rendering process. Rendering phases flow goes to and fro between phases based on the return value of a phase.

For example, if the SetupRender method returns false, then rendering jumps to the CleanupRender phase and vice versa. Refer the below flow in the diagram for a clear understanding of the flow between different phases.

annotation

Simple Component

A simple component called Hello can be created which will have the output message as “Hello, Tapestry”. Below is the code for Hello component and its template.

Hello component can be called in a page template as

Likewise, component can render the same output using MarkupWriter instead of the template as shown below.

Component template can be changed by including the <body /> element as shown in the code block below.

Page template may include body in the component markup as shown below.

Output

Parameters

Main purpose of these parameters is to create a connection between a field of the component and a property / resource of the page to communicate and transfer data between each other. This is called Two Way Data Binding.

For example, a textbox component which is used to represent the age in a user management page gets its initial value through the parameter. Later after the user's age is updated and submitted back, component will send back the updated age through the same parameter.

Declare a field and specify a @Parameter annotation to create a new parameter in the component class. This @Parameter has two optional arguments

  • required − makes the parameter as mandatory. Tapestry raises exception if it is not provided.
  • value − specifies default value of the parameter.

Parameter must be indicated in the page template as attributes of the component tag. Value of the attributes should be specified using Binding Expression / Expansion. Some of the expansions are

  • Property expansion (prop:«val») – Gets data from property of the page class.
  • Message expansion (message:«val») − Gets the data from key defined in index.properties file.
  • Context expansion (context:«val») − Gets the data from web context folder /src/main/webapp.
  • Asset expansion (asset:«val») − Gets the data from resources embedded in jar file, /META-INF/assets.
  • Symbol expansion (symbol:«val») − Gets the data from symbols defined in AppModule.javafile.

Tapestry has many other valuable expansions, some of them are

  • Literal expansion (literal:«val») − A literal string.
  • Var expansion (var:«val») − Allow a render variable of the component to be read or updated.
  • Validate expansion (validate:«val») − A specialized string used to specify the validation rule of an object. For Example, validate:required, minLength = 5.
  • Translate (translate:«val») − Used to specify the Translator class (converting client-side to server-side representation) in input validation.
  • Block (block:«val») − The id of the block element within the template.
  • Component (component:«val») − The id of the another component within the template.

All the above expansions are read-only except Property expansion and Var expansion and are used by the component for exchanging data with the page. While using expansion as attribute values, ${...} should not be used. Instead use the expansion without dollar and braces symbols.

Component Using Parameter

A new component called HelloWithParameter can be created by modifying Hello component to dynamically render the message by adding a name parameter in the component class and changing the component template and page template accordingly.

  • Create a new component class HelloWithParameter.java.
  • Add a private field with name as @Parameter annotation and use the required argument for making it mandatory.

  • Add a private field result with @Property annotation and the result property will be used in the component template. Component template will not have access to fields annotated with @Parameter but can access the fields annotated with @Property. Variables present in component templates are called Render Variables.

  • Add a RenderBody method and copy the value from the name parameter to result property.

  • Add a new component template HelloWithParamter.tml and use the result property for rendering the message.

  • Add a new property, Username in the test page (testhello.java).

  • Use the newly created component in the page template and set the Username property in name parameter of HelloWithParameter component.

Complete listing is shown below

Output

Advanced Parameter

Advanced parameter can contain complete markup. But for this, markup should be specified inside the component tag such as the sub-section in the page template. Built-in component have markup for both success and failure condition. Markup for success is stated as body of the component tag and the markup of failure is stated using an elseparameter.

if component has two parameters

  • test − Simple property based parameter.
  • Else − Advanced parameter which is used to specify alternative markup, if the condition fails

Tapestry will check the value of the test property using below logic and returns true or false. This is called Type Coercion, this is a way to convert an object of one type to another type with the same content.

  • If the data type is String, “True” if non-blank and not the literal string “False” (case insensitive).
  • If the data type is Number, True if non-zero.
  • If the data type is Collection, True if non-empty.
  • If the data type is Object, True (as long as it’s not null).

If the condition passes, the component renders its body; else, it renders the body of the else parameter.

Complete listing is shown below

Component Events / Page Navigation

Tapestry is a collection of Pages which interact with each other. A Component event's main purpose is to provide interaction between pages using server-side events as most of the component events originate from client-side events.

For example, when a user clicks a link in a page, Tapestry will call the same page itself with target information instead of calling the target page and raises a server side event. Tapestry page captures the event, processes the target information and does a server side redirection to the target page.

Tapestry follows a Post/Redirect/Get (RPG) design pattern for navigating a page. In RPG, when a user does a post request by submitting a form, server will process the posted data, but does not return the response directly. Instead, it will do a client-side redirection to another page, which will give the result. RPG pattern is used to avoid duplicate form submissions using browser back button, browser refresh button, etc., Tapestry provide an RPG pattern by providing below two types of request.

  • Component Event Request − this type of request targets a particular component in a page and raises events within the component. This request only does a redirection and does not give the response.
  • Render Request − these types of requests target a page and stream the response back to the client.

URL pattern of the tapestry request should be known to understand the component events and page navigation. The URL pattern for both types of request is shown below

  • Component Event Requests

  • Render Request

If the method name does not have any particular component, then the method will be called for all components with matching events.

OnPassivate and OnActivate Event

OnPassivate is used for providing context information for an OnActivate event handler. In general, Tapestry provides context information and it can be used as an argument in the OnActivateevent handler.

For example, if the context information is 3 of type int, then the OnActivate event can be called as

In some scenario, context information may not be available. To handle this, we can provide the context information to OnActivate event handler through OnPassivate event handler. The return type of the OnPassivate event handler should be used as argument of OnActivate event handler.

Event Handler Return Values

Tapestry issues page redirection is based on the return values of the event handler and this event handler should return any one of the following values.

  • Null Response − Returns null value. Tapestry will construct the current page URL and sends to the client as redirect.

  • String Response − Returns the string value. Tapestry will construct the URL of the page matching the value and sends to the client as redirect.

  • Class Response − Returns a page class. Tapestry will construct the URL of the returned page class and sends to the client as redirect.

  • Page Response − Returns a field annotated with @InjectPage. Tapestry will construct the URL of the injected page and sendS to the client as redirect.

  • HttpError − Returns the HTTPError object. Tapestry will issue a client side HTTP error.

  • Link Response − Link Response returns a link instance directly. Tapestry will construct the URL from Link object and sends to the client as redirect.
  • Stream Response − Stream Response returns StreamResponse object. Tapestry will send the stream as response directly to the client browser and is used to generate reports and images directly and sends it to the client.
  • Url Response − Url Response returns java.net.URL object. Tapestry will get the corresponding URL from the object and sends to the client as redirect.
  • Object Response − Object Response returns any values other than above specified values. Tapestry will raise an error.

Event Context

In general, event handler can get the context information using arguments. For example, if the context information is 3 of type int, then the event handler will be

Tapestry properly handles the context information and provides methods through arguments. Sometimes, Tapestry may not be able to properly handle it due to complexity of the programming.

All rights reserved © 2018 Wisdom IT Services India Pvt. Ltd DMCA.com Protection Status

Apache Tapestry Topics