Saturday, 7 April 2007

Part 1: Demystifying ADF Faces black magic - component categorisation

JDeveloper's JSF design editor makes including all sorts of JSF and ADF Faces components, by drag and drop via the Component Palette, or pure tag coding in the code editor a breeze. What the Component Palette doesn't easily convey is that JSF components can be categorised in a number of different ways and are serviced by a number of Java classes. In fact the whole game looks like black magic unless you bury your head under the magician's table cloth to see how the plumbings work.

Understanding the categorisation and class structure can grow your overall understanding of the JSF framework, including the interaction of its components, the JSF lifecycle, and possibly make debugging an exercise in "ah, that's why that's called" rather than "where the heck am I?", "why did it call that?" and "what voodoo is this?"

Components can be categorised in 2 manners within JSF:
  1. Standard UI Components
  2. Behavioural interfaces
For this "part # 1" post we'll consider the 1st category, and will consider the 2nd category for a later post "part # 2."

The JSF specification defines a number of User Interface (UI) component classes that the majority of standard JSF UI components derive their functionality from. At runtime the JSF UI tags interact with instances of these classes through the attributes the programmer utilises on the JSF UI tags.

All components in JSF inherit from the UIComponentBase which in itself extends UIComponent. At runtime the UIViewRoot contains all the UIComponent instances that make up your JSF web page, essentially a tree of components, and indirectly maintains their state between HTTP request-responses for a particular user session.

Why 2 classes?: UIComponent and UIComponentBase? UIComponent defines all the methods that any subclass component should have, while UIComponentBase takes this further and provides methods and implementations of certain methods that JSF component developers can make use of as a convenience factor to save some coding. For the majority of programmers we wont be doing this, so the other standard JSF UI components that extend UIComponent are what we'll discuss here:
  • UIViewRoot - each JSF web page is represented by a tree of UIComponents (with the subclasses as defined in this bullet point list), that at design time you coded in a .jspx file. The UIViewRoot is central to the JSF lifecycle and its associated phases. The JSF servlet for each session takes care of instantiating the UIViewRoot and its subcomponents, applying any values changes if submitted by the user, as well the state management of components between requests, data validation, data conversions and other work. All these steps commonly referred to as the JSF lifecycle are a separate discussion to this post. However the basic understanding that each web page per user session is represented by a UIViewRoot which can be accessed by the programmer is a worthwhile consideration.
  • UIData - simplistically a table control containing one or more UIColumn components. The UIColumn components and subcomponents are rendered a number of times dependent on the number of rows stored within the UIData's DataModel instance. Put another way, the UIData control is a for-loop construct that for every row in the relating DataModel, will display one set of UIColumn component and subcomponents.
  • UIColumn - in conjunction with the UIData component, a UIColumn represents a single column within the UIData table component. For the UIData DataModel that represents a number of rows, the UIColumn is bound to one item within each row, and the UIColumn is displayed for each row. This means a DataModel with four rows will result in a single UIColumn rendered four times.
  • UIForm - very similar to the HTML form tag, a UIForm component represents a collection of child components that upon submit via a UICommand component, any input control values also submitted to the mid-tier. In other words submittable components must be placed within a UIForm within the overall UIViewRoot.
  • UICommand - a component within a UIForm that when selected by the user forces a submit of the page to the mid-tier, such as a button, hyperlink or menu item. In addition behind the scenes within the JSF world may trigger a backing bean method or other code to perform an action.
  • UIPanel - components that are responsible for laying out other components. These can be very simple from laying subcomponents on a horizontal or vertical plane, to placing the components in relative positions (top, bottom, left, right etc), to complex components that possibly represent menus with predefined graphical elements. Panel controls make heavy use of facets to lay the subcomponents out.
  • UIOutput - any component that holds and displays a value. An output component is read only so inherently the user cannot modify the value.
  • UIInput - is an extension of UIOutput. It holds and displays values, but also allows the user to modify the value which is submitted to the JSF mid-tier for processing, including validation, conversion and storing in the model tier. Unlike the UIOutput tag, the UIInput tag is inherently editable by the user, or in other words not read-only.
  • UISelectBoolean - a type of UIInput control that allows either a true or false value, ultimately rendered as a checkbox or on/off button.
  • UISelectOne - a type of UIInput control that displays a list of values, be it a poplist or multi-item list, where the user may select zero or one value and at most one value only.
  • UISelectMany - a type of UIInput control that displays a list of values, allowing the user to select zero, one or multiple values.
  • UIGraphic - a read only component that displays an image to the user.
  • UIMessage - a component designed to show any error message(s) for a specified component. You see this in the web-world often when you fill out a form, press submit, and the page redisplays showing error message under each component where you didn't meet a specific validation rule.
  • UIMessages - displays all error messages regardless of components in one spot. Again this is commonly seen in the web-world where after filling out a form, a stack of errors is shown at the top of the webpage telling you what you've done wrong.
  • UISelectItem - a child of an UISelectOne or UISelectMany, represents an individual choice of the select controls.
  • UISelectItems - a child of a UISelectOne or UISelectMany, which derives zero, one or many choices for the select controls. Specifically this control must reference through its value an array or Collection of UISelectItem instances, or a Map.
  • UIParameter - a subcomponent for a parent component, that adds any parameter values (name-value pairs) that the parent component needs to complete its execution, just like calling a procedural method requiring parameters.
All the above component types are defined under the JSF spec v1.1 and are available to any JSF implementation, thus why they are a "standard" set. JDev 10.1.3.x uses the JSF v1.1 implementation.

What about ADF Faces though? Isn't ADF Faces Oracle's extension of JSF? Well yes it is.

An inspection of Oracle ADF Faces components reveals a couple of interesting things.

All the classes stored within oracle.adf.view.faces start with the prefix UIX, such as UIXInput and UIXMenu.

Why? Well this shows the roots of ADF Faces and why Oracle is considered experts in the JSF component writer community. UIX harks back to earlier versions of JDeveloper and stood for User Interface for Xml, specifically a web component technology. Web component technology huh? .... doesn't this sound familiar?

When JSF came along Oracle saw a strong match between UIX and JSF, and given the standardized nature of JSF, a good opportunity to upgrade their existing component technology to an industry wide initiative that others could adopt rather than a proprietary technology with the Oracle branding. In fact Oracle has been a key contributor to the JSF spec and their finger prints can be found in a number of JSF areas (among others, check out Adam Winer's work). And their recent-ish donation of the ADF Faces code to Apache under the codename Trinidad shows Oracle is willing to put their money where there mouth is when openly supporting open-source initiatives.

In developing UIX Oracle had learnt a significant amount about web component technology, so much so that in delivering ADF Faces, it can be seen that the ADF Faces heavily extends the base JSF component set with a whole range of extra goodies, ah, components that Oracle deemed necessary. And who are we to argue because a) Oracle is developing these for its own web-enabled applications such as EBS 12, and b) thank goodness we don't have to write these components ourselves.

This leads onto the 2nd revelation when looking at ADF Faces: Beyond the standard components which Oracle has implemented themselves, there are a large amount of additional ADF Faces component types and associated classes. In fact there are so many that the following class diagram really can't be shown without shrinking it right down (and apologies on my part I can't make this more readable):

There are just too many components to list; however we'll list a few of the key additional ADF Faces components over that supplied in JSF:
  • UIXHierachy - base class for any component representing a tree hierarchy, such as menus, trees, tree-tables etc.
  • UIXMenuHierarchy - deriving UIXHierarchy, the set of menu components that display menus with different levels of command options.
  • UIXTree - also deriving UIXHierarchy, a component that visually represents a tree on the web page.
  • UIXChoose - any component that presents a diagram to the user that they can choose an option from (such as a calendar control), rather than a poplist type approach.
  • UIXCommand - similar to the UICommand component in JSF, except also includes support for ADF Faces dialog framework.
Within Oracle's JDev doco is a discussion of how their component tags differ from the JSF spec. While this doesn't mention the component classes directly, it isn't too hard to extrapolate the changes between the component classes:

So in summary we can see that be it JSF or ADF Faces components, or any other JSF component set for that matter, the mechanics of the components are ultimately served by a set of Java classes that plug into the JSF framework. As such how component behave and what they do is not black magic, and given a better understanding of the JSF component framework, your success as a JSF programmer will be increased.

In part 2 of this post, we'll look at the concept of behavioural interfaces and what they provide to each component set.

No comments: