Friday Aug 29, 2008
Friday Aug 29, 2008
by Ed Burns
This Tech Tip introduces a powerful new feature in JavaServer Faces (JSF) 2.0 technology: composite user interface (UI) components. This feature allows you to turn any collection of page markup into a JSF UI component -- with attached validators, converters, action listeners, and value change listeners -- for use by page authors.
In this tip you'll learn you how create a composite UI component and use it in a web application. In doing so, you'll see some of the things that the feature can do. But there are many more things you can accomplish with composite UI components. Also understand that the tip is based on a pre-release version of the JSF 2.0 specification, and an immature implementation of the composite component feature. So don't use the code you develop in this tip in a production JSF 2.0 application without first modifying it to conform to the final version of the JSF 2.0 specification.
The tip assumes that you're already familiar with Java EE 5 web tier technologies, especially with JSF 1.2. A good place to learn about JSF 1.2, is the book JavaServer Faces 1.2: The Complete Reference.
Abstraction and Composite UI Components
Abstraction, that is, generalizing the information content of a concept so that it retains only the information that is relevant for a particular purpose, is a central concept in software development. But how good are software technologies in expressing abstractions? This tip provides an answer to that question for one technology: JSF. The answer is "not as good as it could be."
In spite of its flaws, object-oriented (OO) software continues to be the most popular way that software professionals
do abstraction. From the outset, JSF has claimed to build on OO principles to bring the OO brand of abstraction to the
world of web applications. The user-facing aspect of OO in JSF is the UIComponent ("user" here
means the person using JSF to develop a web application). Unfortunately, the act of creating abstractions using
UIComponent is more complex than necessary.
Several approaches have been taken to solve this problem, the most successful is the templating approach used by
Facelets. This approach involves creating an XHTML page
that contains template text and other JSF components, then treating the XHTML page as a component to be used in other
pages. When you create a component in this way the component is called a composite component. Facelets
composite components are useful, but they do not act as true UIComponents in the page. For example, you
can't attach validators, listeners, or a converter to them.
A real UIComponent must be able to support these operations. What is needed is a way to create composite
components that support all the features of a real UIComponent. This feature should be as simple as possible,
require zero or minimal configuration, should support fast iterative development (without redeployment of the web application),
and support all the features people have come to expect from JSF. And those are the objectives of the
composite UI feature of JSF 2.0.
Install the Software Required to Build and Run the Examples
In this tip you're going to build and run a number of examples that use the composite UI feature. However, before you do that, you'll need to do a little setting up. The machine you're working on must be connected to the Internet and have the proper proxy and firewall settings for all the software used in this tip. In addition, you need to install and configure the required software as follows:
mojarra-2.0.0-SNAPSHOT-glassfish-updater.
Download
the snapshot, then install it.
To install the snapshot in a UNIX platform, enter the following command from the command line:
sudo java -jar <glassfish-jsf-update.jar> <glassfish_inst_ dir>where <glassfish-jsf-update.jar> is the fully-qualified path of the snapshot, and <glassfish_inst_ dir> is the directory where you installed GlassFish v2. For example,
sudo java -jar /Users/edburns/Projects/JavaEE/workareas/mojarra-HEAD/dist/mojarra-2.0.0- SNAPSHOT-glassfish-updater.jar /Applications/NetBeans/glassfish-v2ur2
You'll be prompted to enter a password.
On non-UNIX platforms, you don't prefix the java command with sudo. For example:
java -jar C:\CompUITip\mojarra-2.0.0-SNAPSHOT-glassfish-updater.jar C:\glassfish-v2ur2
Also on non-UNIX platforms, you may need to open your command shell with "Run as Administrator", and enter a password.
In any case, you will need to accept the license agreement. After you accept, you'll see a message similar to the following in the console:
Updating glassfish at /Applications/NetBeans/glassfish-v2ur2 with new JSF jars.
Once the server starts, please visit the admin console GUI. By
default, this is http://localhost:4848/. Doing so will
cause the JSF module to be loaded. You should see a message similar to
the following in the GlassFish V2 output window in the NetBeans 6.1
IDE:
Initializing Mojarra (2.0.0-SNAPSHOT) for context ''
javaee.jar file into the local Maven repository by entering the following commands on
the command line:
where <maven_dir> is the directory where you installed Maven. These commands will install the updated
javaee.jar and jsf-api.jar files into your local Maven repository.
This step is necessary because the examples depend on those JAR files being accessible to Maven.
find ~/.m2/repository/200808-techtip -print
The correct results from the find command should include the following JAR files:
HOMEDIR/.m2/repository/200808-techtip/javaee-api/200808-techtip/javaee-api-200808-techtip.jar
HOMEDIR/.m2/repository/200808-techtip/jsf-api/200808-techtip/jsf-api-200808-techtip.jar
In non-Unix platforms do a search for the two JAR files.
<sample_install_dir>/code,
where <sample_install_dir> is the directory where you unzipped the sample package. For example, if you
extracted the contents to C:\ on a Windows machine, then your newly created directory should be at C:\code.A Simple Example: Your First Composite Component
Follow these steps to create your first composite component.
Step 1. Create the index.xhtml page
When you write a JSF page and include an <h:inputText /> tag in that page, it is said that
your page "uses" an <h:inputText /> component. The same is true of a composite component.
Any page that includes the composite component tag is said to "use" the composite component. A pages that
uses a composite component is also called a using page. In this step, you create a using page for a
composite component that you will create in subsequent steps.
Here is how you create the using page:
<sample_install_dir>/code/example01
and click the Open Project button. This opens the project, jsf-example01, in the Projects window of the IDE.
|
|
Figure 1. The jsf-example01 Project |
|
|
Figure 2. Creating an XHTML File |
Then click the Next button.
This opens a name and location page. Enter index in the XHTML File Name field and click the Finish button.
This creates an XHTML file named index.xhtml.
index.xhtml and select Open.index.xhtml file with the following code:
If you're familiar with Facelets, you'll notice that this is a Facelets page. For JSF 2.0, Facelets is the preferred way to declare JSF Pages. JSP is supported for backwards compatibility, but not all JSF 2.0 features will be available for views using JSP as their page declaration language. In Facelets, pages are authored exclusively in XHTML. JSF UI component libraries are brought into a page by declaring an XML namespace, as shown below:
xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets">
This page uses the jsf/html, the jsf/core, and the jsf/facelets taglibs.
Notice the <h:head> and <h:body> tags in the page. These are two new tags in JSF 2.0.
The <h:head> tag represents the head element of an HTML page. The <h:body> tag
represents the body element of an HTML page You can learn more about these tags in Ryan Lubke's blog
JSF 2.0 New Feature Preview Series
(Part 4): Resource Relocation.
<sample_install_dir>/200808-enterprise-tech-tip/code/example01/target/jsf-example01.war.
The exploded war is in
<sample_install_dir>/200808-enterprise-tech-tip/code/example01/target/jsf-example01/.
.javaee-passwordfile file in your home directory. The contents of the file must
be AS_ADMIN_PASSWORD=adminadmin. Then use the asadmin deploydir command in the
bin subdirectory of the GlassFish installation directory to deploy the exploded war.
For example:
Deploying the application in this way enables you to add XHTML files to the example without redeploying the application. Given the dynamic nature of composite components, this greatly increases your ability to stay in the flow state. The NetBeans Maven plugin automatically copies any XHTML files in your Web Pages section to the deployed application. All you have to do is click the Save button.
Step 2. Add the composite component tag to the using page
Now that you've created the using page (index.xhtml), it’s time to add the composite component tag to
it as follows:
<div> element in the using page:
<ez:loginPanel> </ez:loginPanel>
The prefix "ez" for element "ez:loginPanel" is not bound.
You get this message because you have not yet defined the "ez" prefix.
<html> element in the using page.
Specify the namespace as follows:
xmlns:ez="http://java.sun.com/jsf/composite/ezcomp"
<ez:loginPanel> element. The Facelets implementation in Mojarra simply renders any
component that is not fully defined. Any tag library beginning with http://java.sun.com/jsf/composite/ is assumed to be
a composite component library.
The using page should now look like this:
Step 3. Create the composite component
The design of JSF 2.0 is influenced by the philosophy of convention over configuration, popularized by Ruby on Rails. To realize composite components, this philosophy is combined with the resource loading feature, described in Ryan Lubke’s blog JSF 2.0 New Feature Preview Series (Part 2.1): Resources.
Here's how the approach works in the example application. The JSF runtime takes the name of the composite component
tag in the using page, that is,
loginPanel, and appends .xhtml to it, arriving at loginPanel.xhtml. This value is
the resource-name. The namespace short-name that prefixes the composite component tag, ez:,
has an entry in the <html> element, that is,
xmlns:ez="http://java.sun.com/jsf/composite/ezcomp". The content after
http://java.sun.com/jsf/composite/ in this case, ezcomp, is the library-name.
The library-name and resource-name are used to create a Resource instance.
JSF 2.0 has a method that creates a UIComponent from a Resource. Due to these conventions, any
.xhtml file in a resource library can be accessed as a composite component.
There are several ways to create a resource library, as shown in Ryan’s Blog. Here is one way to do it.
index.xhtml),
you will see a directory named resources. In this
directory is a sub-directory named ezcomp. The name of the
subdirectory (in this case, ezcomp) must correspond to the
end part of the composite xmlns for the namespace short-name that
prefixes the composite component tag.
To create these directories, you can right-click on Web Pages in the Project window and select New then Folder.
index.xhtml file for the using page, create a new XHTML file named
loginPanel.xhtml inside the ezcomp directory.
loginPanel.xhtml and replace its contents with the following code:
Notice the <composite:interface> and <composite:implementation> tags. These are new
in JSF 2.0 and are used to declare a composite component. In the final version of JSF 2.0, these tags will be optional, but
for now they are required.
The <composite:interface> tag declares the usage contract of the composite component. Everything the page
author needs to know to use the composite component is included in this section. The
tag defines the composite component implementation.
|
|
Figure 3. The Composite Component Rendered on the Page |
There isn't much special about what you've done so far. Facelets has always had this kind of templating feature, and in fact that’s what the example is leveraging. In the next issue of the Enterprise Tech Tips, you will learn how to add functionality to the composite component you've created.
Summary
JSF 2.0 provides a new taglib for creating composite components. This taglib, combined with the inclusion of Facelets templating into JSF 2.0, gives you the ability to create composite components, declare the usage contract of composite components, and allow the page author to use those components exactly as if they were true JSF UIComponents.
Further Reading
About the Author
Ed Burns is a senior staff engineer at Sun Microsystems. Ed has worked on a wide variety of client and server-side web technologies since 1994, including NCSA Mosaic, Mozilla, the Sun Java Plugin, Jakarta Tomcat and, most recently JavaServer Faces. Ed is currently the co-spec lead for JavaServer Faces. He is the coauthor of JavaServer Faces 1.2: The Complete Reference and the author of Secrets of the Rockstar Programmers.
these composite elements look like wicket's panels.
Nice addition, but they will not improve the poor built-on-conventions jsf 1.x
Posted by 80.204.43.83 on September 05, 2008 at 07:44 AM PDT #
Thanks for you comments. Perhaps now we'll be able to allow Wicket users to leverage the power of COTS JSF UI Components.
Ed
Posted by Ed Burns on September 08, 2008 at 09:16 AM PDT #
This is a great starting.
Component creation has to get simple as much as possible. Nice work. JSF is the future !!!
Can you put some more complex example and show how this is different from what is available in Facelets.
Question -
1. How we can attach validators and comvertors to it ?
2. Also any plans to harvest JavaFx to make GUIs more rich (skin standardization is also critical, please harvest richfaces assets, as time to market is also critical) ?
Posted by Rahul Mahajan on September 18, 2008 at 10:11 AM PDT #
Can I develop composite component using standard jsf componenets in JSF 1.1. I dont want to use plain html for this but i want to use existing cmponents like HtmlSelectManyBox etc. Also how to develop Ajax functionality in such a component.
Posted by Ahsan Javed on November 25, 2008 at 08:37 AM PST #
It certainly is possible to develop composite components using standard components in JSF 1.1, but you have to do it programmatically and it can be tricky.
Here's a forum thread that is somewhat related:
http://forums.sun.com/thread.jspa?threadID=5319461
Good luck!
Ed
Posted by Ed Burns on December 01, 2008 at 08:44 AM PST #
Warm greetings Ed
Does JSF ver 2.0 will have soo much differents with ver 1.2 ?. I' m already comfortable with ver1.2(although I'm still a newbie).
Do I need to re-learn JSF to comply with ver. 2.0
Posted by faizal on March 29, 2009 at 07:36 AM PDT #
Hi Ed,
Where can I find a complete documentation for JSF2.0 new features ?
Thanks
Faissal
Posted by boutaounte faissal on July 23, 2009 at 03:37 PM PDT #
@boutaounte faissal: Here's a reply from Ed Burns:
I have a webcast that briefly explains all the new features. I describe
how to see it in my blog entry at
<http://weblogs.java.net/blog/edburns/archive/2009/07/recording_of_ma.html>.
Posted by Edward Ort on July 27, 2009 at 08:58 AM PDT #