Kiss My App

Sunday, May 15, 2005

Facelets

I've reappeared from the lab with a new toolkit for developing JavaServer Faces applications; it's called "Facelets". I've recently opened project page at Java.net, https://facelets.dev.java.net/.


Backstory


I, like many in the corporate world, will forever be stuck behind the technology curve thanks to vendor platforms *cough* BEA *cough*. I've been participating in the JSP 2.1 and JSF 1.2 alignment but was constantly reminded that I would never be able to use the technology I was helping to steer for about another 2 years. This assumption is based on the fact that we will only, maybe, be getting JSP 2.0 support this fall with Weblogic 9.0, and that's only if there aren't a bunch of issues with the platform. We've been running on 8.0 now for what seems to be 2 years, and that platform has JSP 1.2 support with an odd interpretation of the Servlet 2.3 spec.


About Facelets


Facelets is a clean slate on the JSP standard if you will. To the JSP developer/designer, things seem extremely normal if you are familiar with JSPX (xml compliant JSP). The major benefit of Facelets is that it's geared at utilizing JSF technology based on the interweaving/tree creation that must occur under the JSF 1.2 specification. Here's a sample taglib file for Facelets.

<facelet-taglib>
<namespace>http://www.mycompany.com/jsf
<tag>
<tag-name>bar</tag-name>
<component>
<component-type>javax.faces.Data</component-type>
<renderer-type>com.mycompany.Bar</renderer-type>
</component>
</tag>
</facelet-taglib>



Why Facelets Will Succeed


Everyone wants to be more designer friendly, and Tapestry seems to be the only choice developers are pursuing. On the other hand, JSF is the standard everyone would like to have happen, but JSF needs a more "pluggable" ViewHandler framework that is more designer/developer friendly.


Developers go through enough work defining UIComponents/Converters/Validators in their faces-config.xml, and Facelets *only* asks them to specify a name alias to plug their objects into their pages (no XML necessary). JSP requires duplicating your UIComponent's properties into a separate class *and* XML file, while Facelets works off of the UIComponent instance itself to properly handle Validators, Converters, Listeners, and Actions in accordance with the JSF 1.2 spec, along with setting ValueExpressions versus literals on the UIComponent's Attribute model auto-magically for you.


Jakarta Velocity has a great API model for environment-independent execution and Facelets was modeled the same way. Unit testing JSF components is extremely easy and doesn't require any Servlet container. Simply initialize a FaceletFactory, and start grabing Facelet instances. This could open the doors for more non-web uses for JSF while providing a JSP-version independent view technology that can be released and used as rapidly as JSF new versions.


Really, Facelets could be used the same as Thinlets or Macromedia's Flex technology to define views/compositions/templates that are completely unrelated to HTML or the web.

Conclusion


While some other frameworks are out there attempting to work with JSF components, they are all too 'middle' ground to be practical. Who wants to re-define their UIComponent's behavior or properties in yet another XML file or properties file? Facelets just does it for you under the JSF 1.2 specification.


I spent a while this afternoon getting Hans Bergsten's "Improving JSF by Dumping JSP" hangman example working under Facelets. With Facelets, I was able to retain the editability factor that he had proposed (same as with Tapestry's jwcid attribute), and reduce page declaration down to a single document without any of the issues he described.


On one hand, just the fact that I was able to swap out all the pages/component definitions within JSF without modifying any of the Java code is a real testament to the flexability of the JSF framework. Secondly, with the above taglib, instead of defining his 'bar' component multiple times within a separate XML file (as his framework uses), you can use your custom 'bar' component like so:


<m:bar id="letters" value="#{visit.letters}" var="letter">
<h:column>
<h:graphicImage value="#{letterImages[letter]}" />
</h:column>
</m:bar>

Facelets automatically takes care of all of the property mappings/valuebindings, validators, listeners, etc-- for you.


I'm not even going to get into the cool templating/decorator features built into Facelets. I'm going to save that for another blog :-)

23 Comments:

Post a Comment

<< Home