Does the JSF book cover the JSF 1.1 spec?

The JavaServer Faces specification version 1.1 was released May 28, 2004. Does this mean that the JavaServer Faces book is now obsolete, since it’s written for the 1.0 version of the specification?
Answer:
The 1.1 version of the specification is what’s formally called a “maintenance release”, but between you and me, “bug fix release” would be a more appropriate label in this case. Most of the changes are corrections of things that were clearly wrong in the 1.0 spec, such as copy/paste errors in JavaDocs method descriptions, descriptions of behavior that didn’t match the Reference Implementation (RI), and descriptions of behavior that resulted in invalid HTML (such as multiple HTML elements with the same idattribute value). The rest are clarifications of details that were underspecified in the 1.0 specification, which are important for JSF implementors but not so important for JSF application developers (the target group for the book).I discovered and reported many of these errors while writing the book, and therefore described the features as they should be rather than how the 1.0 specification incorrectly described them. The book therefore already covers most of the JSF 1.1 changes.

There are, however, a few details (primarily in the Appendices) that are affected by JSF 1.1 and a few things about the JSF 1.1 RI that you should be aware of. They are described below.

Default error messages

The JSF 1.1 RI includes the component client ID in the default error messages, so the message shown in Figure 7-1 looks slightly different. This is a change that isn’t described in the specification so other implementations may not support the message text parameter needed for this to work (which arguably means that the RI isn’t spec-compliant). Including a component identifier in the error messages is a good idea, but the client ID is a very poor identifier, because it can’t be localized and it’s typically a string that the end user doesn’t understand (such as “_id1:_id2”). A future version of the JSF specification will likely address the need for localizable, user friendly component identifiers in the standard messages in a much better way.

New <facet> faces-config.xml element

A new <facet> element can be used in a JSF 1.1 faces-config.xml file to declare facets supported by a component or a renderer, allowing a JSF development tool to list supported facets in addition to properties and attributes. To use this feature, you must use a JSF 1.1 DTD declaration in the faces-config.xmlfile instead of the JSF 1.0 DTD shown in Example E-1, like this:

<!DOCTYPE faces-config PUBLIC     
  "-//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.1//EN"
  "http://java.sun.com/dtd/web-facesconfig_1_1.dtd">

The new <facet> element can be used as a subelement of the <component> and <renderer> elements, just before the <attribute>subelement (see the descriptions for these elements in Appendix E), and has this syntax:

<facet>
  [<description [xml:lang="lang"]>description</description>]*
  [<display-name [xml:lang="lang"]>displayName</display-name>]* 
  [<icon [xml:lang="lang"]>
    [<small-icon>iconPath<small-icon>]
    [<large-icon>iconPath<large-icon>]
  </icon>]*
  <facet-name>facetName</facet-name>
</facet>

Refactoring of the UIInput validate() method

In order to fix a bug with value change events firing for UISelectMany and UISelectOne components when no value was submitted, the UIInput validate() method has been split into three methods. This affects the UIInput method descriptions in Appendix C like this:

New method:
protected Object getConvertedValue(javax.faces.context.FacesContext context, Object newSubmittedValue)

Returns the submitted value after possible conversion to the data type for the local value, performed by calling getConvertedValue() on the component’s Renderer (if any) or getAsObject() on the Converter returned by getConverter (if any) or the Converter returned by the Application createConverter() method for the data type of the ValueBinding (if any). If the conversion fails, calls the addMessage() method of the current FacesContext with a CONVERSION_MESSAGE_ID message.

Modified method:
public void validate(javax.faces.context.FacesContext context)

If getSubmittedValue() returns a non-null value, calls getConvertedValue() to convert the submitted value to the local value data type and calls validateValue() to validate the converted value. If the valid property is still true, calls getValue() to get the previous local value, stores the new local value by calling setValue(), resets the submitted value, and if the previous local value is different than the new local value, queues a ValueChangeEvent.

New method:
protected void validateValue(javax.faces.context.FacesContext context, Object newValue)

If the valid property is true, verifies that the local value isn’t null or an empty String if the required property is set to true, and calls addMessage() with a REQUIRED_MESSAGE_ID message and isValid() with the value false if it is. Otherwise, continues validation by calling the validate() method on each registered Validator instance, followed by a call to the validator method binding (if any), catching any ValidatorException and calling addMessage() with the message from the exception and setValid() with the value false if one is thrown.

This change also affects the method descriptions for UISelectMany and UISelectOne like this:

Removed method:
public void validate(javax.faces.context.FacesContext context)

This method is not overridden in JSF 1.1

New method:
protected void validateValue(javax.faces.context.FacesContext context, Object newValue)

Extends the inherited behavior by verifying that the selected value (or values) matches one of the available choices. If not, calls addMessage() on the current FacesContext with an INVALID_MESSAGE_ID and calls setValid() with the value false.

UIViewRoot getRenderKitId() default

This method returns null in JSF 1.1, not the ID for the default HTML renderkit as it did in 1.0 (which is what the method description in Appendix C says).

UIComponentTag setProperties() behavior

This method description has been updated to match reality in JSF 1.1, which is that it sets the rendered and rendererType properties and nothing else. The method description in Appendix D and the description in Chapter 13 (page 256) incorrectly say that it also sets the id and binding properties, but those are in fact set by the findComponent() method.

Nesting of UIData components

Some improvements have been made in JSF 1.1 to allow UIData components to be used as columns for another UIData component, but it doesn’t go far enough to solve all problems related to this. The book says in Chapter 10 (page 192) that you can nest UIData components, but this is not true for JSF 1.0 and 1.1.

UIOutput/Label limitations lifted

With JSF 1.1, the for attribute for the <h:outputLabel>action element is optional, letting you define the labeled component as a child component instead, e.g.:

<h:outputLabel value="MyLabel">
  <h:inputText value="#{myBean.myValue" />
</h:outputLabel>

The warnings about the RI behavior in Appendix A (about the ordering of the action elements and that the value attribute is ignored) no longer apply for the JSF 1.1 RI.

Rendering of selection components

JSF 1.1 corrects and simplifies the rendering of the UISelectOne/Radio and UISelectMany/Checkbox component/renderer combinations, by rendering the id, style and class attributes on the outer HTML table instead of on a wrapping <style> element, and by no longer rendering the for attribute on the <label> elements wrapping the <input> elements for the choices. This means that the descriptions of these component/renderer combinations in Appendix C and the corresponding tag library actions in Appendix A are slightly off base for JSF 1.1.

Leave a Reply

Your email address will not be published. Required fields are marked *