Apache Tapestry – Overview ”; Previous Next Apache Tapestry is an open source web framework written in Java. It is a component based web framework. Tapestry components are Java Classes. They are neither inherited from a framework specific base class nor implementation of an interface and they are just plain POJOs (Plain old Java Objects). The important feature of the Java used by tapestry is Annotation. Tapestry web pages are constructed by using one or more components, each having a XML based template and component class decorated with a lot of Tapestry”s Annotations. Tapestry can create anything ranging from a tiny, single-page web application to a massive one consisting of hundreds of pages. Benefits of Tapestry Some of the benefits provided by tapestry are − Highly scalable web applications. Adaptive API. Fast and mature framework. Persistent state storage management. Build-in Inversion of Control. Features of Tapestry Tapestry has the following features − Live class reloading Clear and detailed exception reporting Static structure, dynamic behaviors. Extensive use of Plain Old Java Objects (POJOs) Code less, deliver more. Why Tapestry? Already Java has a lot of web frameworks like JSP, Struts, etc., Then, why do we need another framework? Most of the today”s Java Web Frameworks are complex and have a steep learning curve. They are old fashioned and requires compile, test and deploy cycle for every update. On the other hand, Tapestry provides a modern approach to web application programming by providing live class reloading. While other frameworks are introducing lots of interfaces, abstract & base classes, Tapestry just introduces a small set of annotations and still provides the ability to write large application with rich AJAX support. Print Page Previous Next Advertisements ”;
Category: apache Tapestry
Apache Tapestry – Useful Resources ”; Previous Next The following resources contain additional information on Apache Tapestry. Please use them to get more in-depth knowledge on this. Useful Video Courses Apache Spark Online Training Course 47 Lectures 3.5 hours Tutorialspoint More Detail Delta Lake with Apache Spark using Scala 53 Lectures 2 hours Bigdata Engineer More Detail Apache Spark with Scala for Certified Databricks Professional 78 Lectures 5.5 hours Bigdata Engineer More Detail Apache Cassandra for Beginners 28 Lectures 2 hours Navdeep Kaur More Detail NGINX, Apache, SSL Encryption – Training Course 60 Lectures 3.5 hours YouAccel More Detail Learn Advanced Apache Kafka from Scratch Featured 154 Lectures 9 hours Learnkart Technology Pvt Ltd More Detail Print Page Previous Next Advertisements ”;
Apache Tapestry – Annotation
Apache Tapestry – Annotation ”; Previous Next Annotation is a very important feature exploited by Tapestry to simplify the Web Application Development. Tapestry provides a lot of custom Annotations. It has Annotation for Classes, Methods and Member Fields. As discussed in the previous section, Annotation may also be used to override default convention of a feature. Tapestry annotations are grouped into four main categories and they are as follows. Component Annotation Used in Pages, Components and Mixins Classes. Some of the useful annotations are − @Property − It is applicable to fields. Used to convert a field into a Tapestry Property. @Parameter − It is applicable to fields. Used to specify a field as parameter of a component. @Environmental − It is applicable to fields. Used to share a private field between different components. @import − It is applicable to classes and fields. Used to include Assets, CSS and JavaScript. @Path − Used in conjunction with the @Inject annotation to inject an Asset based on a path. @Log − It is applicable to classes and fields. Used for debugging purposes. Can be used emit component”s event information like start of the event, end of the event, etc. IoC annotation Used to inject objects into IoC Container. Some of the useful annotations are − @Inject − It is applicable to fields. Used to mark parameters that should be injected into the IoC container. It marks fields that should be injected into components. @Value − It is applicable to fields. Used along with @inject annotation to inject a literal value instead of a service (which is default behavior of @Inject annotation). Annotation for Data Holding Classes It is used to specify component specific information in a class (usually models or data holding classes) for high level components such as Grid (used to create advanced tabular data such as report, gallery, etc.,) BeanEditForm (Used to create advanced forms) Hibernate (Used in advanced database access), etc. These Annotations are aggregated and packaged into a separate jar without any tapestry dependency. Some of the annotations are − @DataType − It is used to specify the data type of the field. Tapestry component may use this information to create design or markup in the presentation layer. @Validate − It is used to specify the validation rule for a field. These separations enable the Tapestry Application to use a Multi-Tier Design. Print Page Previous Next Advertisements ”;
Forms & Validation Components ”; Previous Next The Form Component is used to create a form in the tapestry page for user input. A form can contain text fields, date fields, checkbox fields, select options, submit button and more. This chapter explains about some of the notable form components in detail. Checkbox Component A Checkbox Component is used to take a choice between two mutually exclusive options. Create a page using the Checkbox as shown below − Checkbox.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; public class Checkbox { @Property private boolean check1; @Property private boolean check2; } Now, create a corresponding template Checkbox.tml as shown below − <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h3> checkbox component</h3> <t:form> <t:checkbox t:id = “check1″/> I have a bike <br/> <t:checkbox t:id = “check2″/> I have a car </t:form> </html> Here, the checkbox parameter id matches to the corresponding Boolean value. Result − After requesting the page,http://localhost:8080/myFirstApplication/checkbox it produces the following result. TextField Component The TextField component allows the user to edit a single line of text. Create a page Text as shown below. Text.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.corelib.components.TextField;public class Text { @Property private String fname; @Property private String lname; } Then, create a corresponding template as shown below – Text.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <p> Form application </p> <body> <h3> Text field created from Tapestry component </h3> <t:form> <table> <tr> <td> Firstname: </td> <td><t:textfield t:id = “fname” /> </td> <td>Lastname: </td> <td> <t:textfield t:id = “lname” /> </td> </tr> </table> </t:form> </body> </html> Here, the Text page includes a property named fname and lname. The component id”s are accessed by the properties. Requesting the page will produce the following result − http://localhost:8080/myFirstApplication/Text PasswordField Component The PasswordField is a specialized text field entry for password. Create a page Password as shown below − Password.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.corelib.components.PasswordField; public class Password { @Property private String pwd; } Now, create a corresponding template file is as shown below − Password.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <p> Form application </p> <h3> Password field created from Tapestry component </h3> <t:form> <table> <tr> <td> Password: </td> <td><t:passwordfield t:id = “pwd”/> </td> </tr> </table> </t:form> </html> Here, the PasswordField component has the parameter id, which points to the property pwd. Requesting the page will produce the following result − http://localhost:8080/myFirstApplication/Password TextArea Component The TextArea component is a multi-line input text control. Create a page TxtArea as shown below. TxtArea.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.corelib.components.TextArea; public class TxtArea { @Property private String str; } Then, create a corresponding template file is as shown below. TxtArea.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h3>TextArea component </h3> <t:form> <table> <tr> <td><t:textarea t:id = “str”/> </td> </tr> </table> </t:form> </html> Here, the TextArea component parameter id points to the property “str”. Requesting the page will produce the following result − http://localhost:8080/myFirstApplication/TxtArea** Select Component The Select component contains a drop-down list of choices. Create a page SelectOption as shown below. SelectOption.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.corelib.components.Select; public class SelectOption { @Property private String color0; @Property private Color1 color1; public enum Color1 { YELLOW, RED, GREEN, BLUE, ORANGE } } Then, create a corresponding template is as follows − SelectOption.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <p> Form application </p> <h3> select component </h3> <t:form> <table> <tr> <td> Select your color here: </td> <td> <select t:type = “select” t:id = “color1”></select></td> </tr> </table> </t:form> </html> Here, the Select component has two parameters − Type − Type of the property is an enum. Id − Id points to the Tapestry property “color1”. Requesting the page will produce the following result − http://localhost:8080/myFirstApplication/SelectOption RadioGroup Component The RadioGroup component provides a container group for Radio components. The Radio and RadioGroup components work together to update a property of an object. This component should wrap around other Radio components. Create a new page “Radiobutton.java” as shown below − Radiobutton.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.annotations.Persist; import org.apache.tapestry5.annotations.Property; public class Radiobutton { @Property @Persist(PersistenceConstants.FLASH) private String value; } Then, create a corresponding template file is as shown below − Radiobutton.tml <html t:type = “Newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h3>RadioGroup component </h3> <t:form> <t:radiogroup t:id = “value”> <t:radio t:id = “radioT” value = “literal:T” label = “Male” /> <t:label for = “radioT”/> <t:radio t:id = “radioF” value = “literal:F” label = “Female”/> <t:label for = “radioF”/> </t:radiogroup> </t:form> </html> Here, the RadioGroup component id is binding with property “value”. Requesting the page will produce the following result. http://localhost:8080/myFirstApplication/Radiobutton Submit Component When a user clicks a submit button, the form is sent to the address specified in the action setting of the tag. Create a page SubmitComponent as shown below. package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.InjectPage; public class SubmitComponent { @InjectPage private Index page1; Object onSuccess() { return page1; } } Now, create a corresponding template file as shown below. SubmitComponent.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h3>Tapestry Submit component </h3> <body> <t:form> <t:submit t:id = “submit1” value = “Click to go Index”/> </t:form> </body> </html> Here, the Submit component submits the value to the Index page. Requesting the page will produce the following result − http://localhost:8080/myFirstApplication/SubmitComponent Form Validation Form validation normally occurs at the server after the client has entered all the necessary data and then submitted the form. If the data entered by a client was incorrect or simply missing, the server would have to send all the data back to the client and request that the form be resubmitted with correct information. Let us consider the following simple example to understand the process of validation. Create a page Validate as shown below. Validate.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.annotations.Persist; public class Validate { @Property @Persist(PersistenceConstants.FLASH)
Apache Tapestry – Components
Apache Tapestry – Components ”; Previous Next As discussed earlier, Components and Pages are the same except that the Page is the root component and includes one or more child components. Components always resides inside a page and do almost all the dynamic functionality of the page. Tapestry components renders a simple HTML links to complex grid functionality with interactive AJAX. A Component can include another component as well. Tapestry components consists of following items − Component Class − The main Java class of the component. XML Template − XML template is similar to the Page template. The component class renders the template as the final output. Some components may not have templates. In this case, the output will be generated by the component class itself using the MarkupWriter class. Body − The component specified inside the page template may have custom markup and it is called “Component body”. If the component template has <body /> element, then the <body /> element will be replaced by the body of the component. This is similar to the layout discussed earlier in the XML template section. Rendering − Rendering is a process which transforms XML template and body of the component into actual output of the component. Parameters − Used to create communication between component & pages and thereby passing data between them. Events − Delegates functionality from components to its container / parent (pages or another component). It is extensively used in page navigation purpose. Rendering The rendering of a component is done in a series of pre-defined phases. Each phase in the component system should have a corresponding method defined by convention or annotation in the component class. // Using annotaion @SetupRender void initializeValues() { // initialize values } // using convention boolean afterRender() { // do logic return true; } The phases, its method name and its annotations are listed below. Annotation Default Method Names @SetupRender setupRender() @BeginRender beginRender() @BeforeRenderTemplate beforeRenderTemplate() @BeforeRenderBody beforeRenderBody() @AfterRenderBody afterRenderBody() @AfterRenderTemplate afterRenderTemplate() @AfterRender afterRender() @CleanupRender cleanupRender() Each phase has a specific purpose and they are as follows − SetupRender SetupRender kick-starts the rendering process. It usually sets up the parameters of the component. BeginRender BeginRender starts rendering the component. It usually renders the begin / start tag of the component. BeforeRenderTemplate BeforeRenderTemplate is used to decorate the XML template, 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 will be called after the component”s body is rendered. AfterRenderTemplate AfterRenderTemplate will be 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 the counterpart of the SetupRender. It releases / disposes all the objects created during rendering process. The flow of the rendering phases is not forward only. It goes to and fro between phases depending 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. To find a clear understanding of the flow between different phases, check the flow in the diagram given below. Simple Component Let us create a simple component, Hello which will have the output message as “Hello, Tapestry”. Following is the code of the Hello component and its template. package com.example.MyFirstApplication.components; public class Hello { } <html xmlns:t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <div> <p>Hello, Tapestry (from component).</p> </div> </html> The Hello component can be called in a page template as − <html title = “Hello component test page” xmlns:t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <t:hello /> </html> Similarly, the component may render the same output using MarkupWriter instead of the template as shown below. package com.example.MyFirstApplication.components; import org.apache.tapestry5.MarkupWriter; import org.apache.tapestry5.annotations.BeginRender; public class Hello { @BeginRender void renderMessage(MarkupWriter writer) { writer.write(“<p>Hello, Tapestry (from component)</p>”); } } Let us change the component template and include the <body /> element as shown in the code block below. <html> xmlns:t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <div> <t:body /> </div> </html> Now, the page template may include body in the component markup as shown below. <html title = “Hello component test page” xmlns:t = “https://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <t:hello> <p>Hello, Tapestry (from page).</p> </t:hello> </html> The output will be as follows − <html> <div> <p>Hello, Tapestry (from page).</p> </div> </html> Parameters The primary purpose of these parameters is to create a connection between a field of the component and a property / resource of the page. Using parameters, component and its corresponding page communicate and transfer data between each other. This is called Two Way Data Binding. For example, a textbox component used to represent the age in a user management page gets its initial value (available in the database) through the parameter. Again, after the user”s age is updated and submitted back, the component will send back the updated age through the same parameter. To create a new parameter in the component class, declare a field and specify a @Parameter annotation. This @Parameter has two optional arguments, which are − required − makes the parameter as mandatory. Tapestry raises exception if it is not provided. value − specifies the default value of the parameter. The parameter should be specified in the page template as attributes of the component tag. The value of the attributes should be specified using Binding Expression / Expansion, which we discussed in the earlier chapters. Some of the expansion which we learned earlier are − Property expansion (prop:«val») − Get the data from property of the page class. Message expansion (message:«val») − Get the data from key defined in index.properties file. Context expansion (context:«val») − Get the data from web context folder /src/main/webapp. Asset expansion (asset:«val») − Get the data from resources embedded in jar file, /META-INF/assets. Symbol expansion (symbol:«val») − Get the data from symbols defined in AppModule.javafile. Tapestry has many more useful expansions, some of which are given below − Literal
Apache Tapestry – Ajax Component ”; Previous Next AJAX stands for Asynchronous JavaScript and XML. It is a technique for creating better, faster and more interactive web applications with the help of XML, JSON, HTML, CSS, and JavaScript. AJAX allows you to send and receive data asynchronously without reloading the web page, so it is fast. Zone Component A Zone Component is used to provide the content (markup) as well as the position of the content itself. The body of the Zone Component is used internally by Tapestry to generate the content. Once the dynamic content is generated, Tapestry will send it to the client, rerender the data in the correct place, trigger and animate the HTML to draw the attention of the user. This Zone component is used along with an EventLink component. An EventLink has option to tie it to a particular zone using the t:zone attributes. Once the zone is configured in EventLink, clicking the EventLink will trigger the zone update. In addition, the EventLink events (refreshZone) can be used to control the generation of dynamic data. A simple example of AJAX is as follows − AjaxZone.tml <html t:type = “Newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <body> <h1>Ajax time zone example</h1> <div class = “div1”> <a t:type = “eventlink” t:event = “refreshZone” href = “#” t:zone = “timeZone”>Ajax Link </a><br/><br/> <t:zone t:id = “timeZone” id = “timeZone”>Time zone: ${serverTime}</t:zone> </div> </body> </html> AjaxZone.java package com.example.MyFirstApplication.pages; import java.util.Date; import org.apache.tapestry5.annotations.InjectComponent; import org.apache.tapestry5.corelib.components.Zone; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.services.Request; public class AjaxZone { @Inject private Request request; @InjectComponent private Zone timeZone; void onRefreshPage() { } Object onRefreshZone() { return request.isXHR() ? timeZone.getBody() : null; } public Date getServerTime() { return new Date(); } } The result will show at: http://localhost:8080/MyFirstApplication/AjaxZone Print Page Previous Next Advertisements ”;
Pages and Components
Apache Tapestry – Pages and Components ”; Previous Next Tapestry Application is simply a collection of Tapestry Pages. They work together to form a well-defined Web Application. Each Page will have a corresponding XML Template and Zero, one or more Components. The Page and Component are same except that the Page is a root component and usually created by an application developer. Components are children of the root Pagecomponent. Tapestry have lots of built-in components and has the option to create a custom component. Pages As discussed earlier, Pages are building blocks of a Tapestry Application. Pages are plain POJOs, placed under – /src/main/java/«package_path»/pages/ folder. Every Page will have a corresponding XML Template and its default location is – /src/main/resources/«package_name»/pages/. You can see here that the path structure is similar for Page and Template except that the template is in the Resource Folder. For example, a user registration page in a Tapestry application with package name – com.example.MyFirstApplication will have the following Page and Template files − Java Class − /src/main/java/com/example/MyFirstApplication/pages/index.java XML Template − /src/main/resources/com/example/MyFirstApplication/pages/index.tml Let us create a simple Hello World page. First, we need to create a Java Class at – /src/main/java/com/example/MyFirstApplication/pages/HelloWorld.java”. package com.example.MyFirstApplication.pages; public class HelloWorld { } Then, create an XML Template at – “/src/main/resources/com/example/MyFirstApplication/pages/helloworld.html”. <html xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd”> <head> <title>Hello World Page</title> </head> <body> <h1>Hello World</h1> </body> </html> Now, this page can be accessed at https://localhost:8080/myapp/helloworld. This is a simple tapestry page. Tapestry offers lot more features to develop dynamic web pages, which we will discuss in the following chapters. Print Page Previous Next Advertisements ”;
Apache Tapestry – Hibernate
Apache Tapestry – Hibernate ”; Previous Next In this chapter, we will discuss about the integration of BeanEditForm and Grid component with Hibernate. Hibernate is integrated into the tapestry through the hibernate module. To enable hibernate module, add tapestry-hibernate dependency and optionally hsqldb in the pom.xml file. Now, configure hibernate through the hibernate.cfg.xml file placed at the root of the resource folder. pom.xml (partial) <dependency> <groupId>org.apache.tapestry</groupId> <artifactId>tapestry-hibernate</artifactId> <version>${tapestry-release-version}</version> </dependency> <dependency> <groupId>org.hsqldb</groupId> <artifactId>hsqldb</artifactId> <version>2.3.2</version> </dependency> Hibernate.cfg.xml <!DOCTYPE hibernate-configuration PUBLIC “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd”> <hibernate-configuration> <session-factory> <property name = “hibernate.connection.driver_class”> org.hsqldb.jdbcDriver </property> <property name = “hibernate.connection.url”> jdbc:hsqldb:./target/work/sampleapp;shutdown = true </property> <property name = “hibernate.dialect”> org.hibernate.dialect.HSQLDialect </property> <property name = “hibernate.connection.username”>sa</property> <property name = “hibernate.connection.password”></property> <property name = “hbm2ddl.auto”>update</property> <property name = “hibernate.show_sql”>true</property> <property name = “hibernate.format_sql”>true</property> </session-factory> </hibernate-configuration> Let us see how to create the employee add page using the BeanEditForm component and the employee list page using the Grid component. The persistence layer is handled by Hibernate module. Create an employee class and decorate it with @Entity annotation. Then, add validation annotation for relevant fields and hibernate related annotation @Id and @GeneratedValue for id field. Also, create gender as enum type. Employee.java package com.example.MyFirstApplication.entities; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import org.apache.tapestry5.beaneditor.NonVisual; import org.apache.tapestry5.beaneditor.Validate; @Entity public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @NonVisual public Long id; @Validate(“required”) public String firstName; @Validate(“required”) public String lastName; @Validate(“required”) public String userName; @Validate(“required”) public String password; @Validate(“required”) public String email; public String phone; @Validate(“required”) public String Street; @Validate(“required”) public String city; @Validate(“required”) public String state; @Validate(“required,regexp=^\d{5}(-\d{4})?$”) public String zip; } Gender.java (enum) package com.example.MyFirstApplication.data; public enum Gender { Male, Female } Create the employee list page, ListEmployee.java in the new folder employee under pages and corresponding template file ListEmployee.tml at /src/main/resources/pages/employee folder. Tapestry provides a short URL for sub folders by removing repeated data. For example, the ListEmployee page can be accessed by a normal URL – (/employee/listemployee) and by the short URL – (/employee/list). Inject the Hibernate session into the list page using @Inject annotation. Define a property getEmployees in the list page and populate it with employees using injected session object. Complete the code for employee class as shown below. ListEmployee.java package com.example.MyFirstApplication.pages.employee; import java.util.List; import org.apache.tapestry5.annotations.Import; import org.apache.tapestry5.ioc.annotations.Inject; import org.hibernate.Session; import com.example.MyFirstApplication.entities.Employee; import org.apache.tapestry5.annotations.Import; @Import(stylesheet=”context:mybootstrap/css/bootstrap.css”) public class ListEmployee { @Inject private Session session; public List<Employee> getEmployees() { return session.createCriteria(Employee.class).list(); } } Create the template file for ListEmployee class. The template will have two main components, which are − PageLink − Create employee link page. Grid − Used to render the employee details. The grid component has sources attributes to inject employee list and include attributes to include the fields to be rendered. ListEmployee.tml (list all employees) <html t:type = “simplelayout” title = “List Employee” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd”> <h1>Employees</h1> <ul> <li><t:pagelink page = “employee/create”>Create new employee</t:pagelink></li> </ul> <t:grid source = “employees” include = “userName,firstName,lastName,gender,dateOfBirth,phone,city,state”/> </html> Create employee creation template file and include BeanEditForm component. The component has the following attributes − object − Includes source. reorder − Defines the order of the fields to be rendered. submitlabel − The message of the form submission button The complete coding is as follows − <html t:type = “simplelayout” title = “Create New Address” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd”> <t:beaneditform object = “employee” submitlabel = “message:submit-label” reorder = “userName,password,firstName,lastName, dateOfBirth,gender,email,phone,s treet,city,state,zip” /> </html> Create employee creation class and include session, employee property, list page (navigation link) and define the OnSuccess event (place to update the data) of the component. The session data is persisted into the database using the hibernate session. The complete coding is as follows − package com.example.MyFirstApplication.pages.employee; import com.example.MyFirstApplication.entities.Employee; import com.example.MyFirstApplication.pages.employee.ListEmployee; import org.apache.tapestry5.annotations.InjectPage; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.hibernate.annotations.CommitAfter; import org.apache.tapestry5.ioc.annotations.Inject; import org.hibernate.Session; public class CreateEmployee { @Property private Employee employee; @Inject private Session session; @InjectPage private ListEmployee listPage; @CommitAfter Object onSuccess() { session.persist(employee); return listPage; } } Add the CreateEmployee.properties file and include the message to be used in form validations. The complete code is as follows − zip-regexp=^\d{5}(-\d{4})?$ zip-regexp-message = Zip Codes are five or nine digits. Example: 02134 or 901251655. submit-label = Create Employee The screenshot of the employee creation page and listing page are shown below − Print Page Previous Next Advertisements ”;
Built-In Components
Apache Tapestry – Built-In Components ”; Previous Next This chapter explains about the built-in components that Tapestry has with suitable examples. Tapestry supports more than 65 built-in components. You can also create custom components. Let us cover some of the notable components in detail. If Component The if component is used to render a block conditionally. The condition is checked by a test parameter. Create a page IfSample.java as shown below − package com.example.MyFirstApplication.pages; public class Ifsample { public String getUser() { return “user1”; } } Now, create a corresponding template file as follows − <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h3>If-else component example </h3> <t:if test = “user”> Hello ${user} <p:else> <h4> You are not a Tapestry user </h4> </p:else> </t:if> </html> Requesting the page will render the result as shown below. Result − http://localhost:8080/MyFirstApplication/ifsample Unless and Delegate Component The unless component is just the opposite of the if component that was discussed above. While, the delegate component does not do any rendering on its own. Instead, it normally delegates the markup to block element. Unless and if components can use delegate and block to conditionally swap the dynamic content. Create a page Unless.java as follows. package com.example.MyFirstApplication.pages; import org.apache.tapestry5.Block; import org.apache.tapestry5.annotations.Property; import org.apache.tapestry5.ioc.annotations.Inject; import org.apache.tapestry5.PersistenceConstants; import org.apache.tapestry5.annotations.Persist; public class Unless { @Property @Persist(PersistenceConstants.FLASH) private String value; @Property private Boolean bool; @Inject Block t, f, n; public Block getCase() { if (bool == Boolean.TRUE ) { return t; } else { return f; } } } Now, create a corresponding template file as follows − <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h4> Delegate component </h4> <div class = “div1”> <t:delegate to = “case”/> </div> <h4> If-Unless component </h4> <div class = “div1”> <t:if test = “bool”> <t:delegate to = “block:t”/> </t:if> <t:unless test = “bool”> <t:delegate to = “block:notT”/> </t:unless> </div> <t:block id = “t”> bool == Boolean.TRUE. </t:block> <t:block id = “notT”> bool = Boolean.FALSE. </t:block> <t:block id = “f”> bool == Boolean.FALSE. </t:block> </html> Requesting the page will render the result as shown below. Result − http://localhost:8080/MyFirstApplication/unless Loop Component The loop component is the basic component to loop over a collection items and render the body for every value / iteration. Create a Loop page as shown below − Loop.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; public class Loop { @Property private int i; } Then, create the corresponding template Loop.tml Loop.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <p>This is sample parameter rendering example…</p> <ol> <li t:type = “loop” source = “1..5” value = “var:i”>${var:i}</li> </ol> </html> Loop component has the following two parameters − source − Collection source. 1…5 is a property expansion used to create an array with a specified range. var − Render variable. Used to render the current value in the body of the template. Requesting the page will render the result as shown below − PageLink Component A PageLink component is used to link a page from one page to another page. Create a PageLink test page as below − PageLink.java. package com.example.MyFirstApplication.pages; public class PageLink { } Then, create a corresponding template file as shown below − PageLink.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <body> <h3><u>Page Link</u> </h3> <div class = “page”> <t:pagelink page = “Index”>Click here to navigate Index page</t:pagelink> <br/> </div> </body> </html> The PageLink component has a page parameter which should refer the target tapestry page. Result − http://localhost:8080/myFirstApplication/pagelink EventLink Component The EventLink component sends the event name and the corresponding parameter through the URL. Create an EventsLink page class as shown below. EventsLink.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; public class EventsLink { @Property private int x; void onActivate(int count) { this.x = x; } int onPassivate() { return x; } void onAdd(int value) { x += value; } } Then, create a corresponding “EventsLink” template file as follows − EventsLink.tml <html t:type = “newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <h3> Event link example </h3> AddedCount = ${x}. <br/> <t:eventlink t:event = “add” t:context = “literal:1”> Click here to add count </t:eventlink><br/> </html> EventLink has the following two parameters − Event − The name of the event to be triggered in the EventLink component. By default, it points to the id of the component. Context − It is an optional parameter. It defines the context for the link. Result − http://localhost:8080/myFirstApplication/EventsLink After clicking the count value, the page will display the event name in the URL as shown in the following output screenshot. ActionLink Component The ActionLink component is similar to the EventLink component, but it only sends the target component id. The default event name is action. Create a page “ActivationLinks.java” as shown below, ActivationLinks.java package com.example.MyFirstApplication.pages; import org.apache.tapestry5.annotations.Property; public class ActivationLinks { @Property private int x; void onActivate(int count) { this.x = x; } int onPassivate() { return x; } void onActionFromsub(int value) { x -= value; } } Now, create a corresponding template file as shown below − ActivationLinks.tml <html t:type = “Newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p = “tapestry:parameter”> <div class = “div1”> Count = ${count}. <br/> <t:actionlink t:id = “sub” t:context = “literal:1”> Decrement </t:actionlink><br/> </div> </html> Here, the OnActionFromSub method will be called when clicking the ActionLink component. Result − http://localhost:8080/myFirstApplication/ActivationsLink Alert Component An alert dialog box is mostly used to give a warning message to the users. For example, if the input field requires some mandatory text but the user does not provide any input, then as a part of validation, you can use an alert box to give a warning message. Create a page “Alerts” as shown in the following program. Alerts.java package com.example.MyFirstApplication.pages; public class Alerts { public String getUser() { return “user1”; } } Then, create a corresponding template file as follows − Alerts.tml <html t:type = “Newlayout” title = “About MyFirstApplication” xmlns:t = “http://tapestry.apache.org/schema/tapestry_5_4.xsd” xmlns:p =
Advanced Features
Apache Tapestry – Advanced Features ”; Previous Next In this chapter, we will discuss a few advanced features of Apache Tapestry in detail. Inversion of Control Tapestry provides built-in Inversion of Control library. Tapestry is deeply integrated into IoC and uses IoC for all its features. Tapestry IoC configuration is based on Java itself instead of XML like many other IoC containers. Tapestry IoC based modules are packaged into JAR file and just dropped into the classpath with zero configuration. Tapestry IoC usage is based on lightness, which means − Small interfaces of two or three methods. Small methods with two or three parameters. Anonymous communication via events, rather than explicit method invocations. Modules Module is a way to extend the functionality of the Tapestry application. Tapestry has both built-in modules and large number of third-party modules. Hibernate is one of the hot and very useful module provided by Tapestry. It also has modules integrating JMX, JPA, Spring Framework, JSR 303 Bean Validation, JSON, etc. Some of the notable third-party modules are − Tapestry-Cayenne Tapestry5-googleanalytics Gang of tapestry 5 – Tapestry5-HighCharts Gang of tapestry 5 – Tapestry5-jqPlot Gang of tapestry 5 – Tapestry5-Jquery Gang of tapestry 5 – Tapestry5-Jquery-mobile Gang of tapestry 5 – Tapestry5-Portlet Runtime Exceptions One of the best feature of the tapestry is Detailed Error Reporting. Tapestry helps a developer by providing the state of art exception reporting. Tapestry exception report is simple HTML with detailed information. Anyone can easily understand the report. Tapestry shows the error in HTML as well as save the exception in a plain text with date and time of the exception occurred. This will help developer to check the exception in production environment as well. The developer can remain confident of fixing any issues like broken templates, unexpected null values, unmatched request, etc., Live Class and Template Reloading Tapestry will reload the templates and classes automatically when modified. This feature enables the immediate reflection of application changes without going through build and test cycle. Also, this feature greatly improves the productivity of the application development. Consider the root package of the application is org.example.myfirstapp. Then, the classes in the following paths are scanned for reloading. org.example.myfirstapp.pages org.example.myfirstapp.components org.example.myfirstapp.mixins org.example.myfirstapp.base org.example.myfirstapp.services The live class reloading can be disabled by setting the production mode to true in AppModule.java. configuration.add(SymbolicConstants.PRODUCTION_MODE,”false”); Unit Testing Unit testing is a technique by which individual pages and components are tested. Tapestry provides easy options to unit test pages and components. Unit testing a page: Tapestry provide a class PageTester to test the application. This acts as both the browser and servlet container. It renders the page without the browser in the server-side itself and the resulting document can be checked for correct rendering. Consider a simple page Hello, which renders hello and the hello text is enclosed inside a html element with id hello_id. To test this feature, we can use PageTester as shown below − public class PageTest extends Assert { @Test public void test1() { Sring appPackage = “org.example.myfirstapp”; // package name String appName = “App1”; // app name PageTester tester = new PageTester(appPackage, appName, “src/main/webapp”); Document doc = tester.renderPage(“Hello”); assertEquals(doc.getElementById(“hello_id”).getChildText(), “hello”); } } The PageTester also provides option to include context information, form submission, link navigation etc., in addition to rendering the page. Integrated Testing Integrated testing helps to test the application as a module instead of checking the individual pages as in unit testing. In Integrated testing, multiple modules can be tested together as a unit. Tapestry provides a small library called Tapestry Test Utilities to do integrated testing. This library integrates with Selenium testing tool to perform the testing. The library provides a base class SeleniumTestCase, which starts and manages the Selenium server, Selenium client and Jetty Instance. One of the example of integrated testing is as follows − import org.apache.tapestry5.test.SeleniumTestCase; import org.testng.annotations.Test; public class IntegrationTest extends SeleniumTestCase { @Test public void persist_entities() { open(“/persistitem”); assertEquals(getText(“//span[@id=”name”]”).length(), 0); clickAndWait(“link = create item”); assertText(“//span[@id = ”name”]”, “name”); } } Development Dashboard The Development dashboard is the default page which is used to identify / resolve the problems in your application. The Dashboard is accessed by the URL http://localhost:8080/myfirstapp/core/t5dashboard. The dashboard shows all the pages, services and component libraries available in the application. Response Compression Tapestry automatically compress the response using GZIP compression and stream it to the client. This feature will reduce the network traffic and aids faster delivery of the page. The compression can be configured using the symbol tapestry.min-gzip-size in AppModule.java. The default value is 100 bytes. Tapestry will compress the response once the size of the response crosses 100 bytes. Security Tapestry provides many options to secure the application against known security vulnerabilities in web application. Some of these options are listed below − HTTPS − Tapestry pages can be annotated with @Secure to make it a secure page and accessible by the https protocol only. Page access control − Controlling the page to be accessed by a certain user only. White-Listed Page − Tapestry pages can be annotated with a @WhitelistAccessOnly to make it accessible only through the localhost. Asset Security − Under tapestry, only certain types of files are accessible. Others can be accessed only when the MD5 hash of the file is provided. Serialized Object Date − Tapestry integrates a HMAC into serialized Java object data and sends it to the client to avoid message tampering. Cross Site Request Forgery − Tapestry provides a 3rd party module called tapestry-csrf-protection to prevent any CSRF attacks. Security Framework integration − Tapestry does not lock into a single authentication / authorization implementation. Tapestry can be integrated with any popular authentication framework. Logging Tapestry provides extensive support for logging, the automatic recording of the progress of the application as it runs. Tapestry uses the de-facto Java logging library, SLF4J. The annotation @Log can be in any component method to emit the entry and exit of the method and the possible exception as well. Also, the Tapestry provided logger object can be