Apache MyFaces Trinidad 1.2 A Practical Guide
Develop JSF web applications with Trinidad and Seam
David Thomas
BIRMINGHAM - MUMBAI
Apache MyFaces Trinidad 1.2 A Practical Guide
Copyright © 2009 Packt Publishing
All rights reserved. No part of this book may be reproduced, stored in a retrieval system, or transmitted in any form or by any means, without the prior written permission of the publisher, except in the case of brief quotations embedded in critical articles or reviews. Every effort has been made in the preparation of this book to ensure the accuracy of the information presented. However, the information contained in this book is sold without warranty, either express or implied. Neither the author, nor Packt Publishing, and its dealers and distributors will be held liable for any damages caused or alleged to be caused directly or indirectly by this book. Packt Publishing has endeavored to provide trademark information about all of the companies and products mentioned in this book by the appropriate use of capitals. However, Packt Publishing cannot guarantee the accuracy of this information.
First published: November 2009
Production Reference: 1031109
Published by Packt Publishing Ltd. 32 Lincoln Road Olton Birmingham, B27 6PA, UK. ISBN 978-1-847196-08-8 www.packtpub.com
Cover Image by Vinayak Chittar (
[email protected])
Credits Author David Thomas Reviewers Cagatay Civici
Editorial Team Leader Akshara Aware Project Team Leader Lata Basantani
Simon Lessard Project Coordinator Acquisition Editor
Rajashree Hamine
Rashmi Phadnis Proofreader Development Editors
Jeff Orloff
Rakesh Shejwal Siddharth Mangarole Technical Editor Mehul Shetty Indexer Monica Ajmera
Graphics Nilesh Mohile Production Coordinator Shantanu Zagade Cover Work Shantanu Zagade
About the Author David Thomas is a developer and technical project manager of Java-based web
applications, and has well over 10 years of experience in various web technologies. He began writing applications based on the Common Gateway Interface (CGI), HTML and Javascript, with a short Java Applets interlude. The main occupation with Java began when Java took charge of the server. A series of Java Servlet applications were developed using an early, self-built Model-2 controller architecture. Java Server Pages (JSP) took hold for a rather long time and a couple of major, increasingly complex, web applications were developed in combination with Struts. This also included the development of major portal applications in the finance and banking sector. Shortly after Java Server Faces 1.2 (JSF) emerged, began the development of a major JSF web application including the development of a high-level framework based on Apache My Faces Trinidad, Facelets and JBOSS Seam in the area of controlling. This project spawned a couple of sub projects, so development continues up to the present day. This is the author's first book which is highly influenced by the accumulated years of his experience in web technology. Apart from his work and the writing of this book, David Thomas likes to write music, sing his own songs, and accompany them on piano and guitar. Other hobbies of his are going on holidays, reading books, walking, swimming, making tea, and taking trains. Furthermore, he is a firm believer in vegetarianism and the responsibility of each human being for her or his well-being and surroundings—in short, of acting locally while thinking globally. Regarding this book he hopes it will be of great value to many people to enjoy an effective and efficient use of Trinidad. I would like to thank my wife for her patience during the writing of this book.
About the Reviewers Cagatay Civici is the PMC member of open source JSF implementation Apache
MyFaces and the project lead of popular PrimeFaces framework. In addition to being a recognized speaker in international conferences such as JSFSummit, JSFDays, and local events, he's an author and technical reviewer of books regarding web application development with Java and JSF. Cagatay is currently working as a consultant and instructor in the UK.
Simon Lessard has been using Java since 2000 with a focus first on game server development, and since 2005 on Web development, when he joined Fujitsu Canada team. Since then, he joined the Apache community working mainly on Apache Trinidad and Apache MyFaces 2.0, and also represents Fujitsu Limited on the JSF 2.0 Expert Group.
Table of Contents Preface Chapter 1: Introducing Trinidad
1 7
Background Overview of Trinidad Characteristics of Trinidad General key criteria for the choosing of Trinidad Seamidad! Ease JSF development with Seam Introduction and overview of Seam Application of Seam with Trinidad
7 9 9 10 13 13 14
Summary
28
Seam conversations and other context management Seam navigation Seam authorization Configuring Trinidad
Chapter 2: Structuring and Building Pages with Facelets Facelet page composition—templating with Facelets Using the template Facelet composition components Creating the composition component The model attribute The visible attribute The msgLabel attribute The labelStyle attribute The required attribute The readOnly attribute The width attribute The margin attribute Declaring the composition component Applying the composition component
16 17 18 24
29
30 34 36 37 38 39 39 40 40 41 41 41 42 43
Table of Contents
Using JSTL for further refinement Typical JSTL structures Things to be aware of when using JSTL and Facelets
45 45 47
Summary
49
Other tags to be aware of Experiencing Facelets in real life projects
Chapter 3: Most Wanted Tags and Tag Attributes
Component library structure Trinidad’s XHTML tag library namespace (trh) Trinidad’s core tag library namespace (tr) Standard tag attributes Standard tag attributes in tag groups Attributes that occur in form and display tags Attributes that occur in command and navigation components Attributes that occur in large input and output components The tag attributes for table, treeTable, and tree The tag attributes for table and treeTable The tag attributes for tree and treeTable The tag attributes for treeTable The tag attributes for tree
Summary
Chapter 4: Rendering Pages Partially Tag-based PPR Finding the trigger
Aspect 1: Ensure that the ID of the PPR trigger is correct Aspect 2: Ensure that the Trinidad configuration is correct Aspect 3: Ensure that the refreshed fields are reset Aspect 4: Ensure proper MVC setup Aspect 5: Ensure that the tag's partialTriggers work Aspect 6: Beware of using PPR with the rendered attribute
PPR with server-side caching by means of the Trinidad pageFlowScope PPR with a tr:selectOneChoice to refresh itself inside a component PPR with a tr:selectOneChoice component and a valueChangeListener PPR with a tr:selectOneChoice component and an actionListener PPR and the rendered attribute Applying PPR naively The right way—a parent component with partial trigger
48 48
51
51 53 54 57 58 58 60 60
61 61 62 63 63
63
65
66 67
68 68 69 69 70 70
70 71 73 76 79
79 81
Java-side PPR using Trinidad's RequestContext Application of PPR from the Java-side
82 83
Summary
85
Step I: Define the PPR source Step II: Add the partial target
[ ii ]
84 84
Table of Contents
Chapter 5: Web Application Groundwork
Navigation Trinidad's Dialog Framework Programmatically creating a dialog Providing the data flow from dialog to dialog Returning from a dialog Authorization Equipping each XHTML with authorization User authorization Internationalization (I18n) I18n on single labels I18n on internal Facelet composition components Polling Setting up the application with Seam-gen Setting up an Eclipse project using Seam-gen Deployment Trinidad-specific and Facelet-related changes to the project files Trinidad-specific changes to the Ant build script Deployment from Eclipse Browser client setup Summary
87
87 90 91 91 92 93 93 94 95 95 95 96 97 99 101 102 105 106 109 111
Chapter 6: Building a Panel-based Content
113
Chapter 7: Building a Form
133
Where the Trinidad panel components live and what they support The accordion and showDetailItem components How to play the panelAccordion The showDetailItem component—press to play an accordion key The combination of accordion and showDetailItem An alternative to pure Facelets The content panel—same soul, different incarnation ControllerPanel keeps the panels under the same roof The toolbar facet Skinning the panels Skinning the accordion and its children Skinning specific properties of the accordion's children Switching the skins on configuration level Summary Building a form Step I: Building the composition components The fieldText component
[ iii ]
113 115 115 116 120 122 123 124 125 128 128 130 130 132 134 135
135
Table of Contents The fieldDate component The fieldNumber component The fieldSelect component
137 139 142
Step II: Building the form
143
Step III: Decorating the form with Trinidad's form submission controls
148
Building a form with several panelFormLayout instances The approach
Processing of a part of a form by means of Trinidad subforms
Step IV: Adding a general message area Summary
Chapter 8: Growing a Tree
Trinidad's tree components ChildPropertyTreeModel—Trinidad's out of the box model Creating a TreeNode Model Building up a tree model Extending the ChildPropertyTreeModel to a Seam component Preparing the panels for navigation Applying the navigation component for basic navigation control Creating the XHTML Using the nodeStamp facet to generate the tree Using a commandLink to create the clickable tree node Passing the node parameters to the navigation control Extending the model-view tree couple Preparations for the new tree model The properties of the AbstractTreeNode The AbstractTreeNode constructors New and modified helper methods The abstracted getters and setters The new TreeNode implementation is now short and easy The new tree node implementation for the new tree model
The new tree model—based on Trinidad's abstract TreeModel Test out the row disclosure by adding a RowDisclosureEvent listener Another tree content to better try tree traversal The getters to access the new state Tree traversal with Trinidad's container methods
The controller-enhanced tree models Testing internal navigation Summary
Chapter 9: The table and treeTable Components The table component The table component in its most minimal usage Adding a selection listener [ iv ]
145 146 149
152 152
153
153 155 155 157 158 159 160 161 161 162 162 163 164 164 164 165 166 166 167
168
169 169 170 171
175 176 177
179
179 180 182
Table of Contents
Adding sorting Adding a button bar Adding detail data sub views and using a POJO data model Adding a search form and paging Adding banding and grids for better visibility Making use of JSF binding and Facelets for further encapsulation Creating the XHTML: the reduction to a single line
The treeTable component The treeTable component in its most minimal usage Adding major table capabilities Summary
Chapter 10: The Chart Component
Where the chart component is and what it supports Bar charts Stacking the bar chart
Pie charts Area charts Line charts ScatterPlot charts Radar charts Funnel charts Gauge charts Summary
184 185 186 188 191 191
194
195 195 196 200
201
201 202
205
207 209 211 214 215 219 219 221
Chapter 11: Building a Wizard
Defining an abstract wizard model The properties of the abstract wizard model Constructors of the abstract wizard Providing the current step, action, and actionListener methods Providing control for the number of wizard steps Providing control for the current step index Providing step incrementation and decrementation Abstract class design aspects Defining the concrete wizard Implementing the wizard's action listeners Implementing the wizard's navigation Implementing a step object Initializing a wizard instance The wizard's application inside the preparation controller Wizard implementation design aspects
[]
223
223 223 224 225 226 226 227 227 228 228 229 230 230 231 232
Table of Contents
Defining the XHTML side—the wizard's face Summary
Chapter 12: Dialogs—Pop-Up Your Web Application! Using the right scope: Seam or only Trinidad How the conversation is kept during a Trinidad dialog Defining a dialog-enabled navigation control Creating Trinidad dialogs in the navigation control Ensuring correct partial page rendering Standard context retrieval methods Calling the proper preparation method The resulting navigation point Making a dialog-enabled tree control Creating concrete tree contents Standard tree methods Providing navigational attributes
The tree's navigation method Revisiting the wizard—few additions make it pop-up Summary
234 237
239
240 242 243 244 245 247 248 249 251 252
253 254
254 256 258
Appendix: References
259
Index
265
Links to the Apache MyFaces Trinidad web site References Chapter 1 Chapter 2 Chapter 3 Chapter 4 Chapter 5 Chapter 6 Chapter 7 Chapter 8 Chapter 9 Chapter 10 Chapter 11 Chapter 12
[ vi ]
259 260 260 260 261 261 261 261 262 262 262 262 263 263
Preface In this book, you will learn how Facelets and Seam are used to get the most out of JSF. You start out by learning where Trinidad comes from and what its aims are. Additionally, you will also learn the often occurring tag attributes and, in particular, Trinidad's Ajax technology. You will implement login, authorization, navigation, internationalization, polling and browser issues with the help of these technologies. You will then use Seam-gen for deployment. As you move through the book, you will develop a web application example where a series of selected Trinidad components are applied and their capabilities explored. Finally, you will master the Trinidad dialog framework, a Trinidad key technology that allows the application of dialogs.
What this book covers
Chapter 1, Introducing Trinidad, introduces you to the Trinidad component library. We give a general idea of this component library, the areas covered by its components, and compare it to other libraries. Finally, the integration of Trinidad and Seam is discussed. Chapter 2, Structuring and Building Pages with Facelets, explains Facelets as a basic means to structure and build pages using Facelet page composition, Facelet composition components, and JSTL. Chapter 3, Most Wanted Tags and Tag Attributes, discusses the Trinidad tags and their attributes in a structured approach. You will gain an insight into the design of Trinidad allowing you to draw an efficient mental map of the library and make an effective selection and application of tags.
Preface
Chapter 4, Rendering Pages Partially, introduces you to the Trinidad's Ajax technology called PPR (Partial Page Rendering). PPR is inspected from two points of view—the pure tag-based partial rendering and the pure Java-side partial rendering techniques. Chapter 5, Web Application Groundwork, teaches you how to develop the basic parts of the web application that serves as our Trinidad example. We present using Seam-gen to rapidly deploy after each change of any file. Chapter 6, Building a Panel-based Content, deals with Trinidad's panelAccordion and showDetailItem components to show how they can be combined to build panel-based, panel-wise collapsible content. Chapter 7, Building a Form, discusses the combinination of Trinidad's tags to Facelet composition components to build highly flexible and well-formatted forms, including messaging support. Chapter 8, Growing a Tree, deals with Trinidad's tree components and models and exemplify their application. We present an effective shortcut that makes Trinidad's tree support an easy, and yet powerful, technology. Chapter 9, The table and treeTable Components, gives an insight to Trinidad's table and treeTable components and exemplifies their application. We apply the components in an increasingly refined way, revealing most of their features one at a time. Chapter 10, The Chart Component, deals with Trinidad's chart component and shows its application. You will learn to competently set up representation parameters, effectively achieving the intended representation focus and thus graphically materializing hidden information in an appropriate way. Chapter 11, Building a Wizard, deals with Trinidad's components to implement a wizard and show their application. We present a solution to avoid an existing Facelet problem. Chapter 12, Dialogs—Pop Up Your Web Application, discusses Trinidad's pop-up window techniques. We revisit Seam conversations to address the specific necessities for pop-up dialogs in Trinidad and Seam. We enhance the web application with a couple of pop-up windows including wizard pop-up support. Appendix, References, provides us with useful references and links related to Apache MyFaces Trinidad.
[]
Preface
Conventions
In this book, you will find a number of styles of text that distinguish between different kinds of information. Here are some examples of these styles, and an explanation of their meaning. Code words in text are shown as follows: "Add a general message area using tr:messages, Trinidad's standard component for this task." A block of code will be set as follows: input11 input12
When we wish to draw your attention to a particular part of a code block, the relevant lines or items will be shown in bold: ��������
Any command-line input or output is written as follows: seam setup
New terms and important words are shown in bold. Words that you see on the screen, in menus or dialog boxes for example, appear in our text like this: "the check method has returned what it could find under the keyword Green, that is, Green Tea". Warnings or important notes appear in a box like this.
Tips and tricks appear like this.
[]
Preface
Reader feedback
Feedback from our readers is always welcome. Let us know what you think about this book—what you liked or may have disliked. Reader feedback is important for us to develop titles that you really get the most out of. To send us general feedback, simply drop an email to
[email protected], and mention the book title in the subject of your message. If there is a book that you need and would like to see us publish, please send us a note in the SUGGEST A TITLE form on www.packtpub.com or email
[email protected]. If there is a topic that you have expertise in and you are interested in either writing or contributing to a book, see our author guide on www.packtpub.com/authors.
Customer support
Now that you are the proud owner of a Packt book, we have a number of things to help you to get the most from your purchase. Downloading the example code for the book Visit http://www.packtpub.com/files/code/6088_Code.zip to directly download the example code. The downloadable files contain instructions on how to use them.
Errata
Although we have taken every care to ensure the accuracy of our content, mistakes do happen. If you find a mistake in one of our books—maybe a mistake in text or code—we would be grateful if you would report this to us. By doing so, you can save other readers from frustration, and help us to improve subsequent versions of this book. If you find any errata, please report them by visiting http://www.packtpub. com/support, selecting your book, clicking on the let us know link, and entering the details of your errata. Once your errata are verified, your submission will be accepted and the errata added to any list of existing errata. Any existing errata can be viewed by selecting your title from http://www.packtpub.com/support.
[]
Preface
Piracy
Piracy of copyright material on the Internet is an ongoing problem across all media. At Packt, we take the protection of our copyright and licenses very seriously. If you come across any illegal copies of our works in any form on the Internet, please provide us with the location address or website name immediately so that we can pursue a remedy. Please contact us at
[email protected] with a link to the suspected pirated material. We appreciate your help in protecting our authors, and our ability to bring you valuable content.
Questions
You can contact us at
[email protected] if you are having a problem with any aspect of the book, and we will do our best to address it.
[]
Introducing Trinidad This chapter introduces the user to Apache MyFaces Trinidad—or, in short, Trinidad. Trinidad is a skinnable, Ajax-enabled, JavaServer Faces (JSF) component library that is highly adaptable to various requirements of today's modern web applications. It is most comprehensive in its functionality and consistent in its API interface and design. Trinidad's large component set arguably satisfies many, if not most, of the requirements that even large web applications nowadays have. Its Ajax framework makes sure pages are rendered in an efficient way. Their look and feel is easily switchable thanks to the underlying skin framework. Trinidad's consistent API interface and design makes JSF development become an effective experience. This chapter will give a general idea of Trinidad. We will cover the following topics: •
Areas covered by Trinidad components
•
An overview of its focus and advantages
•
Criterias to value the quality and the level of the offered components
•
Eased JSF development by combining Trinidad with the Seam web framework
•
Seam used for navigation, context management, and authorization
•
Trinidad's configuration parameters
Background
Trinidad dates back to code development from the beginning of the 21st century. Oracle aimed at the development of a component-based web framework named UIX which would evolve into a core component library for JSF applications and further JSF frameworks themselves. Oracle's early decision to invest in JSF at a time when its future was not at all clear has turned out to be a gamble that paid off. Nowadays, JSF is one of the pivotal technologies when it comes to implementing middle-to-large-scale web applications.
Introducing Trinidad
Oracle's next decision, based on its commitment to the open source Java community, was to donate this framework, originally known as Oracle ADF Faces, to the Apache Software Foundation—which happened in 2006. A part of the development team remains at Oracle, thus ensuring design consistency. The Apache and Oracle team then concentrated on clearing the source from source dependencies to ensure the framework source only consisted of open source code. As an aside, Oracle ADF Faces development still continues, but it is now based on Trinidad. On May 5, 2007, Trinidad left Apache's incubator and joined MyFaces as a subproject. Apache MyFaces is a project of the Apache Software Foundation that is responsible for the open source JSF implementation of the same name that includes a number of sub projects such as Trinidad. By the end of June, Trinidad saw its first release 1.0.1 supporting JSF 1.1. On July 5, Trinidad 1.2.1, the version for JSF 1.2, was released. By the end of 2007 Trinidad started to become a component library with a frequent release cycle, about every two months on average. For more details, refer to the detailed release table in the Appendix, References. The Apache MyFaces mailing list with around 10 to 20 daily entries on Trinidad is another indication of an active user and developer community. Milestone
Version
New Features
2006
Trinidad Incubator
Initial version with closed source bounds
05/05/2007
Release as a MyFaces subproject 1.0.1
JSF 1.1 open source component library
07/05/2007
1.2.1 release (in parallel)
JSF 1.2 open source component library
09/06/2007
1.2.2/1.0.2 release
Addition of aclient-side number converter and skinning performance improvement
10/28/2007
1.2.3/1.0.3 release
Panel improvements, DOM method refinement, configuration improvement, icons and skinning improvements, Ajax improvements
12/10/2007
1.2.4/1.0.4 release
EL improvement, skinning/CSS improvement, internationalization improvements
01/14/2008
1.2.5/1.0.5 release
Sorting improvement, EL improvement, further conversion support
02/11/2008
1.2.6/1.0.6 release
Improvements for skinning and rendering, application scope support,
03/16/2008
1.2.7/1.0.7 release
Skinning improvement
[]
Chapter 1
Milestone
Version
New Features
05/21/2008
1.2.8/1.0.8 release
Skinning improvement, file upload improvement, pop-up dialog improvement, browser support, tree table improvement
08/07/2008
1.2.9/1.0.9 release
Change Management improvements, panel improvement, demo and documentation updates, converter and input field improvements , browser support
Overview of Trinidad
Trinidad is not just a JSF component library. It provides the developer with a modern web framework that focuses on comprehensiveness and a closed-world software design philosophy. This has two general advantages: 1. The user does not need to combine several component libraries. This avoids integration problems is mostly because of the exceptionally large number of components that Trinidad includes. 2. A high degree of consistency is encouraged. As a consequence, similar things are done in a similar way, similar attributes have consistent naming, side effects of other code sources are minimal, error growth is minimal, and so on.
Characteristics of Trinidad
Concretely speaking, the following Trinidad features illustrate this approach's focus on comprehensiveness and closed-world software design: •
Partial page rendering (PPR)—the built-in JSF-Ajax technology is part of practically all Trinidad tags
•
Consistent attribute naming, including sets of recurring attributes throughout Trinidad's tag universe (with different frequency levels of occurrence)
•
A large number of JSF tags is available as a Trinidad version with refinements focused on Trinidad-specific technologies and support, for example, PPR, error or info messaging support, tooltips, labels, layout, and so on
•
Skinning framework—each component is skinnable as well as its parts and attributes
[]
Introducing Trinidad
•
Dialog framework—Trinidad's dialogs allow a web application to work with modal and nestable pop-up windows with no restriction as to its content
•
Trinidad also comes with its own scopes, for example, pageFlowScope to support dialog and page data flow
So now that we have an idea of Trinidad's character, the next obvious question is whether or not it would fit into one of the other JSF project. After all, many component libraries are available, then why should we make Trinidad our next project? It is not easy to make a choice if both variation and complexity are high. If a component is missing, it is usually a better approach to rely on the addition of a JavaScript library, a self-written Facelet or JSF component than trying to integrate another component library that has such a component.
General key criteria for the choosing of Trinidad
No library can be the perfect choice for everyone, as software development projects are simply too different in their requirements. However, if we take a look at general criteria for the choice of a component library where Trinidad is strikingly strong, it will provide a clear and more detailed picture of Trinidad's strengths and help in making your choice. So, in this section we will just give an idea which are the key criterias to the choice of Trinidad and why Trinidad is, if judged from these criteria, a very commendable choice. Further criteria for the choice of a JSF component library can be found in http://www.jsfmatrix.net. Following are the criteria: •
Maturity: Trinidad is a rather mature component library because it has been developed since the beginning of 2000 and has already passed a number of test cycles; moreover, its continuous development and commercial background all point towards a higher degree of maturity.
[ 10 ]
Chapter 1
•
Component range: With these criterias, we typically use the number of components as basic indicator. With well over 100 components Trinidad has a very comprehensive component collection. This collection extends from pure HTML support tags to really substantial components, such as a table viewer, that is, tr:table); a chart component, that is, tr:chart; refined select components such as tr:selectManyShuttle and tr:inputListOfValues; navigation orientation for example, tr:train, nested forms, for instance tr:form/subform; and so on.
•
Interoperability: Trinidad works well with SUN's reference implementation (RI) of JSF and is well combinable with Seam, as we will see throughout this book. However, as is the case with all the other JSF component libraries, it is not well combinable with other JSF component libraries, which is expected to improve in JSF 2.0 with the introduction of standardized Ajax. However, the combination with JavaScript libraries, particularly in combination with Facelets, works very well with Trinidad and represents a worthwhile alternative.
•
Framework character: This is an interesting criterion because it involves aspects like consistency of design and comprehensiveness which are much more the case when dealing with a framework. In comparison, a rather framework-less component library is Tomahawk where each component is much more on its own and can be used rather independently, which is why Tomahawk has a higher interoperability.
•
Support: Support happens mainly through the mailing list, which is quite good considering that it is all free; alternatively, a commercial support by Oracle is surely possible if this is an option you wish to pursue.
•
Facelet support: As already mentioned Trinidad works well with Facelets and is, in fact, the recommendation.
•
Activity example (based on last build): Currently, several developers work on Trinidad, some of them at Oracle, also taking care of design consistency. The community is very much alive as indicated by Trinidad's high release frequency and mailing list traffic.
•
Functional range (functional requirements fulfillment): Of course, this is extremely project-specific, yet the most important criterion as specific, often very singular requirements and their fulfillment, make the biggest difference. Simply speaking, the question to answer is to what degree the library's capability is to fulfill project-specific requirements out of the box? For instance, if a specific requirement is accessibility, refer to the last section of this chapter on configuration. Trinidad has built-in support that is practically unknown to other component libraries.
[ 11 ]
Introducing Trinidad
•
Adequacy: This is a criterion that is closely related to functional range, but more general in terms of the general design philosophy and the user interface guidelines that have materialized in the library. A good example is if the library is capable of supporting a purely keyboard-based navigation, which is the case for Trinidad, or if it is a library that is geared towards mouse-centered direct manipulation, such as JBOSS's RichFaces or SUN's Woodstock. Another example is mobile support, where Trinidad is compatible with a number of major mobile browsers such as Apple IPhone or Microsoft Windows Mobile (refer http://myfaces.apache.org/trinidad/ devguide/mobile.html).
•
Skinnability: A web application is skinnable if there is a mechanism whereby one is able to easily and consistently change a specific look and feel, that is the skin, by configuration. In Trinidad this is efficiently supported as part of css-based, component-wise definitions such as the messages component, which can be skinned individually, and the aspectwise definitions. For example, global selectors, such as AFDarkForeground: alias to set the primary foreground color of the foreground color ramp, so that a couple of well-defined css files, one per skin, is enough to setup and interchange such a skin by configuration.
•
Design quality: This can be measured by the usage flexibility of each component, which is actually very high as one can easily see by looking at the refined and consistently recurring control attributes that many tags have.
•
Documentation: This is provided on the web site and, apart from a couple of broken links on the web site, fairly good. Refer to the Appendix for a list of working links.
•
Browser and platform support: A couple of browsers and platforms are supported, the foremost ones currently are Firefox and Internet Explorer. For current information on browser compatibility, please visit http://myfaces.apache.org/trinidad/browsers.html. Trinidad is compatible with both JSF 1.2 and 1.1 and provides releases for both specifications. A warning to everybody to avoid IE because of security leaks and the many bugs!
We have seen that Trinidad's framework character helps in various aspects when developing a JSF application. However, there are a couple of issues where Trinidad relies on JSF, and JSF itself is not refined enough to cope with them in an easy way.
[ 12 ]
Chapter 1
Seamidad! Ease JSF development with Seam
To be able to better concentrate on the Trinidad component library without having to deal with JSF intricacies and shortcomings, the Seam web framework was introduced. The areas are discussed where Seam comes very favorably into play, that is, scopes such as conversation context, navigation and authorization. Moreover, integration issues are also mentioned. Further details are discussed in the web application chapters.
Introduction and overview of Seam
Trinidad focuses on the viewer side of development, providing concrete JSF components. Seam is a next-generation web framework that has its focus much more on the internal middle tier layer whose domain and controller objects can be managed by Seam to live as Seam objects. This makes it much easier to manage them inside the context of a web application. So the middle-tier covered by Seam involves the management and support for the following types of objects: •
All kinds of controller objects, for example, a navigation controller that encapsulates Trinidad's dialog framework, which is covered throughout this book
•
Model objects which possibly include controller logic to some degree, for instance tree model controllers or a panel model, both to be covered in this book
•
Domain objects that represent the pure object-oriented mapping of database entities as Seam-managed entity beans which reach into the backend, something that is out of focus of this book
Therefore, Seam's emphasis is on providing an overall glue framework for all tiers, with a notable emphasis on the middle-tier. At the same time, this is the main reason why it comes into consideration to fill all the gaps and incongruities left by other frameworks including JSF and Trinidad.
[ 13 ]
Introducing Trinidad
The following image shows the application tiers and the framework responsibilities: backend tier
middle tier
web client (frontend) tier tier
Seam
Trinidad/Facelets
Therefore, to allow one to enjoy the advantages of both frameworks, the approach of combining both frameworks is well worth considering. Thus, for the middle-tier layer, where Trinidad rather leaves us to the mercies of JSF, we could take advantage of Seam. Note that, in the past, such a combination also meant some tedious integration work. In the mean time, integration has been resolved up to a point where, arguably, no serious issues remain. Note that we will still find some integration issues, but we will also resolve them over the course of our Trinidad development sample. All in all, it makes sense to profit from both frameworks and thus, in further combination with Facelets, which is discussed in the following chapter, we will achieve the current, most state-of-the-art JSF web framework combination.
Application of Seam with Trinidad Seam allows us to manage the following areas effectively: •
Conversations and other context management: Seam introduces a conversation context, a new scope that is managed by Seam directly below the session context and that allows, for instance, keeping a possibly long-running context alive only while the domain is being worked on. For example, in operative systems a new file entry implies a new conversation that starts at the time when the file entry is set up by the user, and ends at the time when that entry is really committed and made persistent. Furthermore, all contexts, including the other usual web contexts, become easily manageable because Seam takes advantage of Java 5 and provides annotations that make objects available to contexts and components and allow transferring between them.
[ 14 ]
Chapter 1
•
Navigation: Seam further improves JSF by providing various navigational refinements that simplify and clarify navigation. For instance, JSF's usual faces-config.xml remains rather empty in favor of *.page.xml files that declare navigation page-wise with other, much clearer and simpler tags.
•
Authorization: Seam includes its own authorization framework that can be used to implement a Java or Rule-based authorization system, the latter using JBOSS Rules. It not only supports simple things such as providing a central, self-refinable identity object updated by a self-provided login page, but also more refinement such as annotating the authorization of methods and objects so authorizations are seamlessly checked at method invocation time.
There are many more improvements that we will come across in the course of building our sample web application. But first, let us further illustrate the main areas where Seam comes into play. The following screenshot shows the login screen based on Seam support for internationalization and authorization:
[ 15 ]
Introducing Trinidad
Seam conversations and other context management Seam has a couple of useful annotations, whereby one is enabled to annotate the desired context of objects as part of their declarations in the respective class source. The objects may be of any type, for example, controller or domain data objects. Mainly the following are applied: •
@In(scope=ScopeType., required=, value=""): This annotation enables the value of the variable's from the indicated context to be assigned to the annotated object, often from the current CONVERSATION,
which is carried out by Seam's context management mechanism. The shortest annotation is simply @In where the object is taken from the first context it appears in a certain priority order, see below, either using the name indicated by the value parameter or the name of the object itself. The required parameter allows the injected object to be null if required="false", otherwise an exception is thrown. •
@Out(scope=ScopeType., required=, value=""): Antonymically to @In, this annotation enables the annotated object's value to be assigned to the variable in the indicated context, which again is carried out by Seam's context management mechanism, often in the current CONVERSATION. The shortest annotation is simply @Out.
•
@Name(): This annotation is used to make an object to a
Seam component; it needs to get a Seam component name so it can be addressed from other contexts. This annotation is precondition to using the aforementioned @In/@Out inside of a Seam component.
Note that both annotations presuppose an object and interaction design architecture to get the desired object value updates and readings at the right times. For our sample web application, we will use a simple architecture that applies web tier viewer models, thus leaving out project-dependent discussion of domain tier architecture, and use them as domain objects and Seam components as controller objects. The controllers will use the @In and @Out annotation to date up conversation-bound domain objects by user-form interaction. In other situations, it may be that an injection or projection is required where no annotation-based injection or projection automation occurs. Alternatively, Seam provides Java-API-based manipulation by means of Seam's Contexts object and their getters and setters: org.jboss.seam.context.Contexts.lookupInStatefulContexts(). get("") org.jboss.seam.context.Contexts.lookupInStatefulContexts(). set("")
[ 16 ]
Chapter 1
Alternatively, one may explicitly provide the context to lookup, for example, the conversation context: org.jboss.seam.context.Contexts.getConversationContext().get("") org.jboss.seam.context.Contexts.getConversationContext().set("")
Furthermore, when using @In or @Out without further indication or the lookupInStatefulContexts method or to access an object or a component from a JSF page, one has to take the priority into account, whereby Seam tries to find an object in the various contexts from top to bottom: •
Event context: Typically, this is the JSF request scope so event context objects are alive during the time the respective request is going on
•
Page context: This is the JSF page scope level, practically analogous to the JSP page context
•
Conversation context: As already mentioned, this is a special context provided by Seam to support stateful browser client or server interaction in an elegant and transparent way
•
Session context: This is the usual HttpSession context
•
Business process context: Along with the conversation context, this is another Seam-specific context; it is provided for JBPM processes because of Seam's support of business process handling with JBPM
•
Application context: This is the usual web application scope as known in the servlet world
Seam navigation
Seam navigation is organized in two levels: 1. pages.xml: This is the main file where all navigation is typically declared that is not on a single page-level, for example, general navigation for login, security, and error handling. Note that one could also declare the navigation of a single page in this file, but doing this for all pages means a large navigation that is potentially less manageable. However, it would all at least be -Struts-wise- in one place. 2. *.page.xml: This refers to the navigation for each JSF page. It is optional if only pages.xml is used.
[ 17 ]
Introducing Trinidad
Typically, each page is declared in a block as follows:
The view-id identifies the page by its path plus its name, and always begins with a /, for example, /login.xhtml. Then, there is one or more navigation blocks that identify the action-triggered navigation. For instance, in the preceding example we see that on completion of a certain controller method, methodName, the view is redirected to another page—JSF-Page-View-ID-2. Although we will further elaborate on the navigation declarations, the basic navigation is going to be this way. The reason for this is that we want to keep any complexity away from the page definitions, for example, decision logic on where to navigate to will be kept in the respective controllers. The following image shows single page navigation, based on Seam's pages XML: frontend tier (pages.xml)
JSF-Page-View-ID
step 2: redirect
JSF-Page-View-ID-2
step 1: action
controller # {controllerName.methodName} middle tier
Seam authorization
To protect our pages from unwanted access, we will take advantage from the so called simplified mode of Seam security. This will spare us further authorization work that would distract us from our real target in this book. Seam's simplified authorization provides objects for identifying, and authenticating, the user and setting up roles and rights. We will profit from this authorization framework which, by the way, may be quite easily extended to use a rule-engine, for example, JBOSS Rules, for more refined rule-based permission evaluations. [ 18 ]
Chapter 1
Carry out the following steps to setup Seam authorization in a purely Java-based way without a rule-engine that suffices for our requirements to protect our pages depending on certain roles such as admin, editor, or reader: 1. Setup Seam's component configuration by modifying components.xml to use the Seam Security component. Here, we would use the namespace:
xmlns:security="http://jboss.com/products/seam/security"
And the schema: http://jboss.com/products/seam/security http://jboss.com/products/seam/security-2.0.xsd
2. We then declare the object and its method to use for authentication:
3. Now, we can implement the authenticator object, which is basically an override of the authenticate method:
@Name("authenticator") public class Authenticator { @Logger Log log;@In Identity identity; @In SampleSession sampleSession;
/*** write your authentication logic here, return true * if authentication succeeded otherwise false * @return true authentication succeeded */ public boolean authenticate() { SampleIdentity sampleIdentity = (SampleIdentity) identity; sampleIdentity.addRole("reader sampleSession.startSession( sampleIdentity.getUsername(), LocaleSelector.instance().getLocale() ); return true; } }
[ 19 ]
Introducing Trinidad
4. Now, implement the identity object, a specialization of Seam's Identity (SampleIdentity), and contain additional fields. Note that the imports and other minor declarations are skipped for readability of the essential material. Also be aware that we use a couple of annotations required by Seam to replace Seam's standard identity component (refer to the link of Seam's reference in the appendix for further explanation):
@Name("org.jboss.seam.security.identity") @Scope(ScopeType.SESSION) @Install(precedence = Install.APPLICATION) @BypassInterceptors @Startup @SuppressWarnings(value = "serial") public class SampleIdentity extends Identity { private static Set authorizedMethod = new HashSet(); private Set roles = new HashSet(); private final static String hasRight = "hasRight"; public final static String roleEditor = "roleEditor"; public final static String roleReader = "roleReader"; public final static String roleAdmin = "roleAdmin"; static { authorizedMethod.add( hasRight + "Editor"); authorizedMethod.add( hasRight + "Reader"); authorizedMethod.add( hasRight + "Admin"); } @Override public boolean addRole(String role) { roles.add(role); return super.addRole(role); }
5. We have defined a couple of simple rights and roles which illustrates the principle. Next, we need to override identity's evaluation method to be able to call our additional hasRight* methods:
@Override protected boolean evaluateExpression(String expr) { if (authorizedMethod.contains(expr)) { FacesContext context = FacesContext.getCurrentInstance(); MethodExpression method = context.getApplication(). getExpressionFactory(). [ 20 ]
Chapter 1
createMethodExpression(context.getELContext(), "#{identity." + expr + "}", Boolean.class, new Class[] {}); return (Boolean) method.invoke(context.getELContext(), new Object[] {}); } else return super.evaluateExpression(expr); }
6. Now we only have to describe the conditions to fulfill the respective rights which we simply reduce to checking if a suitable role has been assigned. This would be less simple in real life:
///////////// has rights behaviour /////////////// public boolean hasRightEditor() { if (!isLoggedIn()) return false; return hasRole(roleEditor); } public boolean hasRightReader() { if (!isLoggedIn()) return false; return hasRole(roleReader); } public boolean hasRightAdmin() { if (!isLoggedIn()) return false; return hasRole(roleReader); } public boolean hasRightAccess() { return (hasRightAdmin() || hasRightReader() || hasRightEditor()); } }
7. Finally, we setup the login.xhtml and apply Trinidad for the first time in this book:
[ 21 ]
Introducing Trinidad ����������
Note that we will discuss all of these tags in detail in the upcoming chapters of this book. The following are a few points that need to be understood: •
"trh" is the Trinidad tag library dealing with Trinidad's (X)HTML support tags.
•
"tr" is Trinidad's core tag library dealing with the main stuff provided
•
There are many tags known to XHTML and JSF that Trinidad provides its own version for. This is what has already been alluded to by mentioning Trinidad's design philosophy—to be fully supported by Trinidad. Those tags are provided in order to ensure their fully correct, and framework-consistent functionality, for instance the trh:body could be refreshed partially using PPR which would work, as all Trinidad tags support it apart from a few exceptions where it does not make sense.
•
panelFormLayout allows one to build a form without taking much care as to its formatting. Trinidad does the formatting for us and even considers internationalization!
•
Regarding navigation, the most important component here is notably the command button that calls Seam's identity object's login method that passes control to our authenticated method.
by Trinidad.
[ 22 ]
Chapter 1
The following screenshot shows the login page for Seam:
Now, we can secure pages and methods from unwanted access simply by annotating them before the respective method using: @Restrict("hasRightEditor") private void insert() {...}
And inside of a page declaration in pages.xml or *.page.xml directly on the most upper block level: hasRightAccess
After successful login, Seam automatically passes a information box, as shown in the following screenshot:
[ 23 ]
Introducing Trinidad
So if, for example, the user is not logged in, and a certain page's access is restricted with hasRightAccess, we get an error message on the current page an error is logged by Seam: org.jboss.seam.security.NotLoggedInException at org.jboss.seam.security.Identity.checkRestriction(Identity.java:185) at org.jboss.seam.navigation.Page.checkPermission(Page.java:218) at org.jboss.seam.navigation.Page.preRender(Page.java:238) at org.jboss.seam.navigation.Pages.preRender(Pages.java:316) at org.jboss.seam.jsf.SeamPhaseListener.preRenderPage(SeamPhaseListener. java:560) at org.jboss.seam.jsf.SeamPhaseListener.beforeRenderResponse(SeamPhaseLis tener.java:471) at org.jboss.seam.jsf.SeamPhaseListener.beforeServletPhase(SeamPhaseListe ner.java:144) at org.jboss.seam.jsf.SeamPhaseListener.beforePhase(SeamPhaseListener. java:114) at com.sun.faces.lifecycle.LifecycleImpl.phase(LifecycleImpl.java:222)
The following screenshot shows the error message produced by Seam which is declared in the pages.xml:
Configuring Trinidad
There are a few configuration options that are important, and possibly subtle enough, to warrant a mention here before going ahead with our sample web application. Two types of parameters can be distinguished by the location of their appearance, which is either in the web.xml or the more specific trinidad-config.xml.
Important Trinidad configuration parameters in the web.xml The following pair of parameters appear in the web.xml file and is of particular interest for the current development work and the pop-up dialogs:
[ 24 ]
Chapter 1
•
CHECK_FILE_MODIFICATION: This web.xml context parameter makes quite a bit of sense to set it to true during development and test cycles because it
allows one to modify the css skin definitions on-the-fly, and to see the results of the changes immediately. •
ENABLE_LIGHTWEIGHT_DIALOGS: This web.xml context parameter is
very important for our later exploration into Trinidad's modal pop-up dialogues; if not set to true we would get simple JavaScript-based browser window dialogs! The following screenshot shows the comparison of a simple JavaScript-based browser window dialog (on the left) and a Trinidad lightweight dialog (on the right):
•
DISABLE_CONTENT_COMPRESSION: This is an important means to reduce the size of the resulting XHTML, which is achieved by using cryptically short names for the applied css styles. However, for development this parameter should remain false as the names practically become illegible and error analysis becomes difficult.
•
DEBUG_JAVASCRIPT: Like the foregoing compression parameter, switching
this one on disables compressed Javascript output so comments, spaces, and the original un-obfuscated naming becomes visible.
[ 25 ]
Introducing Trinidad
Important Trinidad configuration parameters in the trinidad-config.xml
The rest of the more interesting parameters are located in Trinidad's own configuration file, the trinidad-config.xml: •
: It is almost always a good idea to have this option activated throughout the development and test cycles as the rendered code is much more readable and understandable then and so easier to debug.
•
: We keep this option DISABLED because we do not
want to get into intricacies on the client side. We prefer a server-side approach that usually pays off by means of reliability and clearer architecture.
•
: This should be set to default so today's XHTML code is produced, such as input components using "label for" that make it more user-friendly. Furthermore, setting this parameter to 'screenReader' improves the look and feel under a screen reader; to remove any kind of accessibility support that optimizes output size, set this parameter to 'inaccessible'.
•
: This allows further refinement of accessibility with values high-contrast to indicate the preference for a highly contrasting look and 'large-fonts' to indicate the preference for bigger fonts; both values can be set at the same time.
•
: This specifies the maximum number of pageFlowScopes that are kept at the same time; pageFlowScope is Trinidad's
own scope to keep models, and any other data, for Trinidad's pop-up dialogs.
Other configuration parameters
For the sake of completeness, let us briefly mention here the other, less generally crucial and more specifically valuable, parameters that may as well be applied:
Special parameters in the trinidad-config.xml A series of parameters are provided that allow setting up help, internationalization, number formats, and one's own file upload processor class. These parameters have been explained as follows: •
oracle-help-servlet-url: It allows setting the URL to link to a separate help system, for instance OHW, Oracle's Help for the Web.
•
time-zone: It is used to set a default time zone independent of the respective browser.
[ 26 ]
Chapter 1
•
right-to-left: It is used to set an opposite language reading direction, for
•
currency-code: It is used to define a default for the format of currency
•
formatting-locale: It is applied in converters by default if no other locale
•
two-digit-year-start: It is used to set the assumed year default offset for two-digit year inputs, for example, 12/02/08.
•
number-grouping-separator: It is used to define the character used as the
• •
example, Hebrew. It defaults to false.
fields in the case that a currency format is not provided within the respective Trinidad-based converter. is explicitly used inside the respective converter.
separator of number groups.
decimal-separator: It is used to define the character used as the
decimal separator.
uploaded-file-processor: It is used to indicate another class than the Trinidad default UploadedFileProcessor that is responsible for processing files to be uploaded. This class must implement Trinidad's file upload processor interface.
Special parameters in the web.xml for further optimization Finally, there are a few further parameters devised for optimization under certain conditions: •
CLIENT_STATE_METHOD: It serves to switch Trinidad's page state control
•
CLIENT_STATE_MAX_TOKENS: It serves to explicitly set the number of tokens
•
that by default manages page state in the session scope, and uses tokens to distinguish several windows that display the same page. If this behavior is not desirable and page state is preferred to be managed on the browser client side, set this parameter to all. Otherwise to explicitly switch to the default, set it to token.
applied in Trinidad's page state control, the default being 15. If this value is surpassed, the page state for the oldest pages will not be available depending on the amount of the surpassed value. This is particularly relevant for pages accessed through the back button. CACHE_VIEW_ROOT: It is used to achieve an increase in PPR performance; Trinidad caches UIViewRoot, the JSF view tree, by default. However, this behavior might collide with other JSF frameworks. This is why this parameter allows switching it off.
[ 27 ]
Introducing Trinidad
•
USE_APPLICATION_VIEW_CACHE: When this parameter is set to true, Trinidad aims at higher scalability by caching the view state of initially rendered pages in the application scope. This saves a great deal of memory that would otherwise be spent across different page instances for each user; the default is false as an application's functionality may be broken by this optimization technique because it assumes the initial rendering of pages not to vary according to the user.
•
CHANGE_PERSISTENCE: It is used to enable change persistence of component
state that is modifiable by the user e.g. collapsing a tree node, or by clicking on detail display of a table row; the component state is usually kept in the session scope, which is the default implementation (refer to Trinidad's SessionChangeManager class), so the parameter value for enabling this component state persistence is 'session'.
Summary
In this chapter, we have had our first encounter with Apache MyFaces Trinidad. We learned that it is not only a component library, but also a JSF framework. Tinidad, together with another web framework called Seam, results in the most state-of-the-art JSF web framework combination. We have approached Trinidad from several angles. Historically, it developed from Oracle's component-based web framework UIX into a JSF component library with a strong framework character. Its software design follows a philosophy of comprehensiveness and closed-world design that make for a powerful JSF framework with a large component set and many underlying framework features. These features go far beyond the typical support given by a regular JSF component library—accessibility, mobile phone support, mouse-independent keyboard support, and built-in Ajax to name a few. Moreover, we learned about specific criteria to show where Trinidad is strikingly advanced in comparison with JSF libraries. We introduced Seam as a second web framework applied to support JSF where Trinidad relies on it. Namely in navigation, scopes and general features to satisfy typical web application requirements, such as authorization which we have implemented in an exemplary fashion. Finally, we saw which configuration parameters are supported by Trinidad to set up its various aspects such as internationalization, change management, optimization, and others—once again revealing Trinidad's comprehensiveness.
[ 28 ]
Structuring and Building Pages with Facelets Facelets is a JSF view handler which has, by now, become kind of an official standard for JSF view technology devised for browser clients. As a further refined and extended version, it will become a part of the standard JSF libraries in the oncoming JSF version 2.0, including an option that allows using the current Facelets version. Originally, Facelets have been introduced to cover the main deficiencies of the default combination of JSF with JSP view technology. Therefore, problems regarding incompatibilities between the JSF and JSP life cycle could be fixed by using Facelets as a view handler that is natural to JSF. Moreover, various other enhancements, such as page composition techniques and composition components, have been introduced. Let's have a look at the main benefits of the newly introduced enhancements to Facelets: •
Facelet page composition as a technique to compose one's pages as an assembly of parts
•
Facelet composition components allow a simple yet effective encapsulation of reusable parametrized page parts that look and feel like JSF components
•
Using JSTL for further refinement of composition components
Actually, the developers who happen to know Tiles and Tapestry will feel quite at home with Facelets because the assembly of a page by Facelet page composition resembles Tiles, while creating and using a Facelet component is similar to creating and using a Tapestry component. Moreover, JSTL can be used within a Facelet component so that the developer can take advantage from tag-based control structures such as conditionals like choose-when-otherwise. Although declarative, it is somewhat comparable to Java inline code on a JSP page; however, on the one hand it appears encapsulated inside of components and, on the other hand, it acts inside specific phases of the JSF life cycle. So there is a big difference to JSP because the process is controlled by the Facelets view handler which is specifically
Structuring and Building Pages with Facelets
designed for JSF. Whereas in JSP, pages are simply compiled to create servlets that output exactly what appears on the page in the order of their appearance, in JSF there is a specific servlet called FacesServlet that puts a life cycle into action which essentially comprises, among other phases, the construction of a view tree of stateful components and its rendering. Generally, the Facelets view handler provides controls to take part in these major phases, providing templating and control flow means for the view tree construction as well as for the tree rendering. The reader will see how the web application's basic structure is formed by Facelets. While the theory of composition components is presented here, their practice is shown in detail in the upcoming chapters.
Facelet page composition—templating with Facelets
Usually, the creation of pages is based on layout templates that make page creation more efficient as the assembly-wise rendering of page parts, that occur in several or all pages, is rendered by a specific engine that is focused towards such a task; in our case, Facelets. What is more, the developer is able to concentrate on the page-specific issues, repeated parts are not re-stated on the page, and the developer does not have to bother with such parts anymore if they are introduced as parts of a layout template. Therefore, by using a couple of basic Trinidad tags, we go ahead and apply them as part of a general template that defines the layout of all the pages of our sample Trinidad web application: