The Many Faces of JavaServer Faces (JSF), Page 2
The set of UI components supplied with JSF is extensible - indeed, the extensions will no doubt outstrip the supplied components in short order, by extending and combining them into more sophisticated UI elements. Tool developers can now create UI-paint applications that manipulate JSF components, as opposed to framework-specific elements (such as tags or XSL elements), allowing the page designer to say "place one of this type of component here, bind it to the following property in the application". JSF components are associated with a value from the underlying application logic, and may also be associated with one or more "events" that are triggered when the component is manipulated by the user. These events (the equivalent of a "submit" operation in Servlet terms) trigger a chain of processing called the JSF life cycle. In brief, this life cycle applies the request parameters to the "tree" of non-visual components (creating one, if necessary), performs necessary validations and type conversions, then passes the values to the application logic and triggers the method associated with the event. This life cycle can be abbreviated by, for example, validation errors, causing the page to be re-displayed with all of the values intact (in addition, likely, to an error message telling the user why the validation failed). This avoids calling the application logic entirely, at least for simple validations. Assuming the validations and conversions were successful, the application did get called, the "tree" of components associated with this request is cached for later use, and the application goes on to the next logical step. Some events will return to the same logical page, so the ability to cache the page of components and their associated values allows the page to be modified and then re-displayed: for example, filling in a customer code might result in the customer name being displayed alongside it, while the remainder of the page remains the same. This kind of "state saving" helps build web-based applications that provide a more "traditional" UI experience for the user, while not imposing an additional burden on the application logic.
JSF, therefore, has very little impact on the application logic of your existing programs, assuming they were written in a fashion that employs model/view/controller separation. This allows JSF to be phased-in, as opposed to making it a "rip and replace" technology.
While some work is required to integrate the JSF life cycle into existing frameworks, it's API is factory and interface based, allowing just such integration. An effort is already underway to allow Struts to take advantage of JSF, as they have quite similar approaches in many ways even now. JSF's reference implementation includes a powerful tag library, where JSP pages can easily be created to pick elements from the UIView (the response "tree" of non-visual components) for display in specific locations on the finished page. Like any other JSP, the "decorative" portion of the page can be interlaced with these components as necessary to create an user-friendly layout.
What if you're not currently using Struts or even JSP, though, are you out in the cold as far as JSF is concerned? Not at all.
While it has been discussed a few times how it's quite possible to generate XML from JSP pages, then transform that XML via XSL, this many-layered approach has many hardened veterans in the web application business shaking their heads over the complexity. We'll try a more direct approach.
Let's look at an example of one of my favorite UI frameworks: Cocoon - (or the UI-handling portion of Cocoon, in any case, as Cocoon of course can do far more than render a UI). Cocoon does not expose a Servlet request and response directly to the application logic (or the controller Servlet) for manipulation. Instead, it uses the powerful approach of pipelines, where a pipeline begins (usually) with a generator, passes through one or more transformers, and then into a serializer. Another way to initiate a pipeline is through an action, which is the common way in Cocoon to invoke server-side application logic. This logic then deposits an XML fragment in the session context, which is in turn extracted by a special Generator, and on to the normal pipeline flow.
Let's see (at a high level) how JSF fits into this model: Pipelines deal (with few exceptions) with XML, so we need a way to Map the UIView produced by JSF into an XML document. This is the "RenderKit" portion of JSF - the layer where the non-visual component begins it's conversion into a concrete representation on the screen. Fortunately, the structured and hierarchical form of a UIView can easily be serialized into XML. With this approach, the UI does not "pick" elements from the UIView to be laid out on the page (or other display device), the entire UIView "tree" is available - so how do we format it into a user-friendly view? The most common mechanism for this in Cocoon is XSL transformation: our XML representation of the whole UIView can be passed through a stylesheet, taking advantage of the unique and powerful structure of XSL, to produce a proper rendering of the XML as needed for different displays. The most common output might be HTML, but nothing prevents us from applying a stylesheet to produce PDF, SVG, RTF, XSL or any other format we might care to imagine. Our stylesheets can even be hierarchical: we can have one "root" stylesheet that knows how to render all of the common elements, such as UISelectOne's, UIText, and so forth, then "import" that stylesheet and override selectively. On this page we want all UIText fields to have a green background? No problem, just override that one template. We can also drive *which* elements we render, doing the same kind of selective process as we might do in a JSP page, by overriding the top-level UIView template, then calling render templates one at a time for explicitly named elements. As you can see, JSF's power can easily be linked with a UI mechanism that is not JSP-oriented, while at the same time preserving the power of it's standardization.
While we've only examined one possible integration of JSF into an existing UI-rendering technology, there are of course many other possibilities. Each UI framework so far has had to come up with an answer to the issues addressed by JSF: how to map application logic to a non-visual representation, how to lay out components on a page, how to render a given component in the appropriate display language, and so forth. Ideally, each of the many different UI approaches can take advantage of the common backbone of JSF, allowing the goal of portability to be achieved not only between systems, but also between entire frameworks, while maintaining the unique advantages that set them apart from other UI technologies and approaches. This will require a willingness to set aside any "not invented here" syndrome in order to reap the advantages of standardization, thus enabling the entire Java industry to benefit, as well as the users of any one framework.
About the AuthorMichael Nash is the president of JGlobal Limited, a software development, consulting, training and support company specializing in open source Java technologies. He is also a core developer of the Keel meta-framework, the author of two books and a number of articles and papers about next-generation web-application development with Java, and a member of the JSR-127 (JavaServer Faces) Expert Group. He can be reached at firstname.lastname@example.org.