Specification: Jakarta Server Faces

Version: 3.0

Status: Final

Release: September 23, 2020

Copyright © 2018, 2020 Eclipse Foundation. https://www.eclipse.org/legal/efsl.php

Eclipse Foundation Specification License

By using and/or copying this document, or the Eclipse Foundation document from which this statement is linked, you (the licensee) agree that you have read, understood, and will comply with the following terms and conditions:

Permission to copy, and distribute the contents of this document, or the Eclipse Foundation document from which this statement is linked, in any medium for any purpose and without fee or royalty is hereby granted, provided that you include the following on ALL copies of the document, or portions thereof, that you use:

  • link or URL to the original Eclipse Foundation document.

  • All existing copyright notices, or if one does not exist, a notice (hypertext is preferred, but a textual representation is permitted) of the form: "Copyright (c) [$date-of-document] Eclipse Foundation, Inc. [url to this license]"

Inclusion of the full text of this NOTICE must be provided. We request that authorship attribution be provided in any software, documents, or other items or products that you create pursuant to the implementation of the contents of this document, or any portion thereof.

No right to create modifications or derivatives of Eclipse Foundation documents is granted pursuant to this license, except anyone may prepare and distribute derivative works and portions of this document in software that implements the specification, in supporting materials accompanying such software, and in documentation of such software, PROVIDED that all such works include the notice below. HOWEVER, the publication of derivative works of this document for use as a technical specification is expressly prohibited.

The notice is:

"Copyright (c) 2018 Eclipse Foundation. This software or document includes material copied from or derived from [title and URI of the Eclipse Foundation specification document]."

Disclaimers

THIS DOCUMENT IS PROVIDED "AS IS," AND THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION MAKE NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, NON-INFRINGEMENT, OR TITLE; THAT THE CONTENTS OF THE DOCUMENT ARE SUITABLE FOR ANY PURPOSE; NOR THAT THE IMPLEMENTATION OF SUCH CONTENTS WILL NOT INFRINGE ANY THIRD PARTY PATENTS, COPYRIGHTS, TRADEMARKS OR OTHER RIGHTS.

THE COPYRIGHT HOLDERS AND THE ECLIPSE FOUNDATION WILL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE DOCUMENT OR THE PERFORMANCE OR IMPLEMENTATION OF THE CONTENTS THEREOF.

The name and trademarks of the copyright holders or the Eclipse Foundation may NOT be used in advertising or publicity pertaining to this document or its contents without specific, written prior permission. Title to copyright in this document will at all times remain with copyright holders.

Preface

This is the Jakarta Server Faces 3.0 specification.

Changes between 3.0 and 2.3

Backward Compatibility with Previous Versions

Jakarta Faces 3.0 has a breaking change due to the namespace change from javax.faces to jakarta.faces.

Other Jakarta Platform Specifications

Jakarta Faces is based on the following Jakarta specifications:

Jakarta Servlet Specification, version 5.0 (Servlet) https://github.com/eclipse-ee4j/servlet-api

Jakarta WebSocket, version 2.0 https://github.com/eclipse-ee4j/websocket-api

Jakarta Contexts and Dependency Injection for Java 3.0 https://github.com/eclipse-ee4j/cdi

Jakarta Expression Language 4.0 https://github.com/eclipse-ee4j/el-ri

Jakarta JSON Processing, version 2.0 https://github.com/eclipse-ee4j/jsonp

Jakarta Server Pages Specification, version 3.0 https://github.com/eclipse-ee4j/jsp-api/

Jakarta Standard Tag Library, version 2.0 https://github.com/eclipse-ee4j/jstl-api

Therefore, a Jakarta Faces container must support all of the above specifications. This requirement allows faces applications to be portable across a variety of Jakarta Faces implementations.

In addition, Jakarta Faces is designed to work synergistically with other web-related Java APIs, including:

Portlet Specification, 1.0 JSR-168 http://jcp.org/en/jsr/detail?id=168

Portlet Specification, 2.0 JSR-286 http://jcp.org/en/jsr/detail?id=286

Portlet Specification, 3.0 JSR-286 http://jcp.org/en/jsr/detail?id=362

JSF Portlet Bridge Specification, JSR-301 http://jcp.org/en/jsr/detail?id=301

The following documents and specifications of the World Wide Web Consortium will be of interest to Jakarta Faces implementors, as well as developers of applications and components based on Jakarta Server Faces.

Hypertext Markup Language (HTML), version 4.01 http://www.w3.org/TR/html4/

Extensible HyperText Markup Language (XHTML), version 1.0 http://www.w3.org/TR/xhtml1

Extensible Markup Language (XML), version 1.0 (Second Edition) http://www.w3.org/TR/REC-xml

The class and method Javadoc documentation for the classes and interfaces in jakarta.faces (and its subpackages) are incorporated by reference as requirements of this Specification.

The Jakarta Server Pages and Facelet tag library for the HTML_BASIC standard RenderKit is specified in the VDLDocs and incorporated by reference in this Specification.

Terminology

The key words MUST, MUST NOT, REQUIRED, SHALL, SHALL NOT, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL in this document are to be interpreted as described in

Key words for use in RFCs to Indicate Requirement Levels (RFC 2119) http://www.rfc-editor.org/rfc/rfc2119.txt

Providing Feedback

We welcome any and all feedback about this specification. Please email your comments to <[email protected]>.

Please note that, due to the volume of feedback that we receive, you will not normally receive a reply from an engineer. However, each and every comment is read, evaluated, and archived by the specification team.

Acknowledgements

The authors would like to thank the original JCP JSR-372 Expert Group and Contributors.

Ed Burns

Manfred Riem

Frank Caputo

Cagatay Civici

Ken Fyten

Neil Griffin

Josh Juneau

Brian Leatham

Kito Mann

Michael Müller

Paul Nicolucci

Bauke Scholtz

Arjan Tijms

Leonardo Uribe

The editors would like to recognize the following individuals who have contributed to the success of Jakarta Server Faces over the years.

Dan Allen

Thomas Andraschko

Thomas Asel

Jennifer Ball

Lincoln Baxter III

Hans Bergsten

Shawn Bayern

Joseph Berkovitz

Dennis Byrne

Pete Carapetyan

Ryan DeLaplante

Keith Donald

Jim Driscoll

Hanspeter Duennenberger

Ken Finnigan

Amy Fowler

Mike Freedman

David Geary

Manfred Geiler

Ted Goddard

Juan Gonzalez

Jeremy Grelle

Rick Hightower

Jacob Hookom

Justyna Horwat

Alexander Jesse

Max Katz

Roger Keays

Gavin King

Roger Kitain

Eric Lazarus

Jason Lee

Felipe Leme

Cody Lerum

Alberto Lemos

Ryan Lubke

Barbara Louis

Martin Marinschek

Kumar Mettu

Craig McClanahan

Pete Muir

Bernd Müller

Michael Müller

Hans Muller

Brendan Murray

Michael Nash

Imre Osswald

Joe Ottinger

Ken Paulsen

Dhiru Pandey

Raj Premkumar

Werner Punz

Matt Raible

Hazem Saleh

Andy Schwartz

Yara Senger

Stan Silvert

Vernon Singleton

Bernhard Slominski

Alexander Smirnov

Thomas Spiegel

Kyle Stiemann

James Strachan

Jayashri Visvanathan

Ana von Klopp

Matthias Wessendorf

Adam Winer

Mike Youngstrom

John Zukowski

1. Overview

Jakarta Server Faces (hereafter Jakarta Faces) is a user interface (UI) framework for Java web applications. It is designed to significantly ease the burden of writing and maintaining applications that run on a Java application server and render their UIs back to a target client. Jakarta Faces provides ease-of-use in the following ways:

  • Makes it easy to construct a UI from a set of reusable UI components

  • Simplifies migration of application data to and from the UI

  • Helps manage UI state across server requests

  • Provides a simple model for wiring client-generated events to server-side application code

  • Allows custom UI components to be easily built and re-used

Most importantly, Jakarta Faces establishes standards which are designed to be leveraged by tools to provide a developer experience which is accessible to a wide variety of developer types, ranging from corporate developers to systems programmers. A “corporate developer” is characterized as an individual who is proficient in writing procedural code and business logic, but is not necessarily skilled in object-oriented programming. A “systems programmer” understands object-oriented fundamentals, including abstraction and designing for re-use. A corporate developer typically relies on tools for development, while a system programmer may define his or her tool as a text editor for writing code.

Therefore, Jakarta Faces is designed to be tooled, but also exposes the framework and programming model as APIs so that it can be used outside of tools, as is sometimes required by systems programmers.

1.1. Solving Practical Problems of the Web

Jakarta Faces’s core architecture is designed to be independent of specific protocols and markup. However it is also aimed directly at solving many of the common problems encountered when writing applications for HTML clients that communicate via HTTP to a Java application server that supports servlets and Jakarta Server Pages based applications. These applications are typically form-based, and are comprised of one or more HTML pages with which the user interacts to complete a task or set of tasks. Jakarta Faces tackles the following challenges associated with these applications:

  • Managing UI component state across requests

  • Supporting encapsulation of the differences in markup across different browsers and clients

  • Supporting form processing (multi-page, more than one per page, and so on)

  • Providing a strongly typed event model that allows the application to write server-side handlers (independent of HTTP) for client generated events

  • Validating request data and providing appropriate error reporting

  • Enabling type conversion when migrating markup values (Strings) to and from application data objects (which are often not Strings)

  • Handling error and exceptions, and reporting errors in human-readable form back to the application user

  • Handling page-to-page navigation in response to UI events and model interactions.

1.2. Specification Audience

The Jakarta Server Faces Specification , and the technology that it defines, is addressed to several audiences that will use this information in different ways. The following sections describe these audiences, the roles that they play with respect to Jakarta Faces, and how they will use the information contained in this document. As is the case with many technologies, the same person may play more than one of these roles in a particular development scenario; however, it is still useful to understand the individual viewpoints separately.

1.2.1. Page Authors

A page author is primarily responsible for creating the user interface of a web application. He or she must be familiar with the markup and scripting languages (such as HTML and JavaScript) that are understood by the target client devices, as well as the rendering technology (such as Jakarta Server Pages ) used to create dynamic content. Page authors are often focused on graphical design and human factors engineering, and are generally not familiar with programming languages such as Java or Visual Basic (although many page authors will have a basic understanding of client side scripting languages such as JavaScript).

Page authors will generally assemble the content of the pages being created from libraries of prebuilt user interface components that are provided by component writers, tool providers, and Jakarta Faces implementors. The components themselves will be represented as configurable objects that utilize the dynamic markup capabilities of the underlying rendering technology. When Jakarta Server Pages are in use, for example, components will be represented as Jakarta Server Pages custom actions, which will support configuring the attributes of those components as custom action attributes in the Jakarta Server Pages page. In addition, the pages produced by a page author will be used by the Jakarta Faces framework to create component tree hierarchies, called “views”, that represent the components on those pages.

Page authors will generally utilize development tools, such as HTML editors, that allow them to deal directly with the visual representation of the page being created. However, it is still feasible for a page author that is familiar with the underlying rendering technology to construct pages “by hand” using a text editor.

1.2.2. Component Writers

Component writers are responsible for creating libraries of reusable user interface objects. Such components support the following functionality:

  • Convert the internal representation of the component’s properties and attributes into the appropriate markup language for pages being rendered (encoding).

  • Convert the properties of an incoming request—parameters, headers, and cookies—into the corresponding properties and attributes of the component (decoding)

  • Utilize request-time events to initiate visual changes in one or more components, followed by redisplay of the current page.

  • Support validation checks on the syntax and semantics of the representation of this component on an incoming request, as well as conversion into the internal form that is appropriate for this component.

  • Saving and restoring component state across requests

As will be discussed in Rendering Model,” the encoding and decoding functionality may optionally be delegated to one or more Render Kits , which are responsible for customizing these operations to the precise requirements of the client that is initiating a particular request (for example, adapting to the differences between JavaScript handling in different browsers, or variations in the WML markup supported by different wireless clients).

The component writer role is sometimes separate from other Jakarta Faces roles, but is often combined. For example, reusable components, component libraries, and render kits might be created by:

  • A page author creating a custom “widget” for use on a particular page

  • An application developer providing components that correspond to specific data objects in the application’s business domain

  • A specialized team within a larger development group responsible for creating standardized components for reuse across applications

  • Third party library and framework providers creating component libraries that are portable across Jakarta Faces implementations

  • Tool providers whose tools can leverage the specific capabilities of those libraries in development of Jakarta Faces-based applications

  • Jakarta Faces implementors who provide implementation-specific component libraries as part of their Jakarta Faces product suite

Within Jakarta Faces, user interface components are represented as Java classes that follow the design patterns outlined in the JavaBeans Specification. Therefore, new and existing tools that facilitate JavaBean development can be leveraged to create new Jakarta Faces components. In addition, the fundamental component APIs are simple enough for developers with basic Java programming skills to program by hand.

1.2.3. Application Developers

Application Developers are responsible for providing the server-side functionality of a web application that is not directly related to the user interface. This encompasses the following general areas of responsibility:

  • Define mechanisms for persistent storage of the information required by Jakarta Faces-based web applications (such as creating schemas in a relational database management system)

  • Create a Java object representation of the persistent information, such as Jakarta Persistence entities, and call the corresponding beans as necessary to perform persistence of the application’s data.

  • Encapsulate the application’s functionality, or business logic, in Java objects that are reusable in web and non-web applications, such as CDI beans.

  • Expose the data representation and functional logic objects for use via Jakarta Faces, as would be done for any servlet- or Jakarta Server Pages-based application.

Only the latter responsibility is directly related to Jakarta Faces APIs. In particular, the following steps are required to fulfill this responsibility:

  • Expose the underlying data required by the user interface layer as objects that are accessible from the web tier (such as via request or session attributes in the Servlet API), via value reference expressions , as described in Standard User Interface Components.”

  • Provide application-level event handlers for the events that are enqueued by Jakarta Faces components during the request processing lifecycle, as described in Invoke Application.

Application modules interact with Jakarta Faces through standard APIs, and can therefore be created using new and existing tools that facilitate general Java development. In addition, application modules can be written (either by hand, or by being generated) in conformance to an application framework created by a tool provider.

1.2.4. Tool Providers

Tool providers , as their name implies, are responsible for creating tools that assist in the development of Jakarta Faces-based applications, rather than creating such applications directly. Jakarta Faces APIs support the creation of a rich variety of development tools, which can create applications that are portable across multiple Jakarta Faces implementations. Examples of possible tools include:

  • GUI-oriented page development tools that assist page authors in creating the user interface for a web application

  • IDEs that facilitate the creation of components (either for a particular page, or for a reusable component library)

  • Page generators that work from a high level description of the desired user interface to create the corresponding page and component objects

  • IDEs that support the development of general web applications, adapted to provide specialized support (such as configuration management) for Jakarta Faces

  • Web application frameworks (such as MVC-based and workflow management systems) that facilitate the use of Jakarta Faces components for user interface design, in conjunction with higher level navigation management and other services

  • Application generators that convert high level descriptions of an entire application into the set of pages, UI components, and application modules needed to provide the required application functionality

Tool providers will generally leverage the Jakarta Faces APIs for introspection of the features of component libraries and render kit frameworks, as well as the application portability implied by the use of standard APIs in the code generated for an application.

1.2.5. Jakarta Faces Implementors

Finally, Jakarta Faces implementors will provide runtime environments that implement all of the requirements described in this specification. Typically, a Jakarta Faces implementor will be the provider of a Jakarta EE application server, although it is also possible to provide a Jakarta Faces implementation that is portable across Jakarta EE servers.

Advanced features of the Jakarta Faces APIs allow Jakarta Faces implementors, as well as application developers, to customize and extend the basic functionality of Jakarta Faces in a portable way. These features provide a rich environment for server vendors to compete on features and quality of service aspects of their implementations, while maximizing the portability of Jakarta Faces-based applications across different Jakarta Faces implementations.

1.3. Introduction to Jakarta Faces APIs

This section briefly describes major functional subdivisions of the APIs defined by Jakarta Faces. Each subdivision is described in its own chapter, later in this specification.

1.3.1. package jakarta.faces

This package contains top level classes for the Jakarta Faces API. The most important class in the package is FactoryFinder , which is the mechanism by which users can override many of the key pieces of the implementation with their own.

Please see FactoryFinder.

1.3.2. package jakarta.faces.application

This package contains APIs that are used to link an application’s business logic objects to Jakarta Faces, as well as convenient pluggable mechanisms to manage the execution of an application that is based on Jakarta Faces. The main class in this package is Application .

Please see Application.

1.3.3. package jakarta.faces.component

This package contains fundamental APIs for user interface components.

1.3.4. package jakarta.faces.component.html

This package contains concrete base classes for each valid combination of component + renderer.

1.3.5. package jakarta.faces.context

This package contains classes and interfaces defining per-request state information. The main class in this package is FacesContext , which is the access point for all per-request information, as well as the gateway to several other helper classes.

Please see FacesContext.

1.3.6. package jakarta.faces.convert

This package contains classes and interfaces defining converters. The main class in this package is Converter .

Please see Conversion Model.

1.3.7. package jakarta.faces.el

As of version 1.2 of this specification, all classes and interfaces in this package have been deprecated in favor of the Unified Expression Language (EL) from Jakarta Server Pages 2.1.

1.3.8. package jakarta.faces.flow and jakarta.faces.flow.builder

The runtime API for Faces Flows.

Please see FlowHandler.

1.3.9. package jakarta.faces.lifecycle

This package contains classes and interfaces defining lifecycle management for the Jakarta Server Faces implementation. The main class in this package is Lifecycle . Lifecycle is the gateway to executing the request processing lifecycle.

1.3.10. package jakarta.faces.event

This package contains interfaces describing events and event listeners, and concrete event implementation classes. All component-level events extend from FacesEvent and all component-level listeners extend from FacesListener .

1.3.11. package jakarta.faces.render

This package contains classes and interfaces defining the rendering model. The main class in this package is RenderKit . RenderKit maintains references to a collection of Renderer instances which provide rendering capability for a specific client device type.

Please see Rendering Model.

1.3.12. package jakarta.faces.validator

Interface defining the validator model, and concrete validator implementation classes.

Please see Validation Model

1.3.13. package jakarta.faces.webapp

Classes required for integration of Jakarta Faces into web applications, including a standard servlet, base classes for Jakarta Server Pages custom component tags, and concrete tag implementations for core tags.

2. Request Processing Lifecycle

Web user interfaces generally follow a pattern where the user-agent sends one or more requests to the server with the end goal of displaying a user-interface. In the case of Web browsers, an initial HTTP GET or POST request is made to the server, which responds with a document which the browser interprets and automatically makes subsequent requests on the user’s behalf. The responses to each of these subsequent requests are usually images, JavaScript files, CSS Style Sheets, and other artifacts that fit “into” the original document. If the Jakarta Faces lifecycle is involved in rendering the initial response, the entire process of initial request, the response to that request, and any subsequent requests made automatically by the user-agent, and their responses, is called a Faces View Request/Response for discussion. The following graphic illustrates a Faces View Request/Response.

image

Each Faces View Request/Response goes through a well-defined request processing lifecycle made up of phases . There are three different scenarios that must be considered, each with its own combination of phases and activities:

  • Non-Faces Request generates Faces Response

  • Faces Request generates Faces Response

  • Faces Request generates Non-Faces Response

Where the terms being used are defined as follows:

  • Faces Response —A response that was created by the execution of the Render Response phase of the request processing lifecycle.

  • Non-Faces Response —A response that was not created by the execution of the render response phase of the request processing lifecycle. Examples would be a servlet-generated or JSP-rendered response that does not incorporate Jakarta Faces components, a response that sets an HTTP status code other than the usual 200 (such as a redirect), or a response whose HTTP body consists entirely of the bytes of an in page resource, such as a JavaScript file, a CSS file, an image, or an applet. This last scenario is considered a special case of a Non-Faces Response and will be referred to as a Faces Resource Response for the remainder of this specification.

  • Faces Request —A request that was sent from a previously generated Faces response . Examples would be a hyperlink or form submit from a rendered user interface component, where the request URI was crafted (by the component or renderer that created it) to identify the view to use for processing the request. Another example is a request for a resource that the user-agent was instructed to fetch an artifact such as an image, a JavaScript file, a CSS stylesheet, or an applet. This last scenario is considered a special case of a Faces Request and will be referred to as a Faces Resource Request for the remainder of this specification.

  • Non-Faces Request —A request that was sent to an application component (e.g. a servlet or Jakarta Server Pages page), rather than directed to a Faces view.

In addition, of course, your web application may receive non-Faces requests that generate non-Faces responses. Because such requests do not involve Jakarta Server Faces at all, their processing is outside the scope of this specification, and will not be considered further.

READER NOTE: The dynamic behavior descriptions in this Chapter make forward references to the sections that describe the individual classes and interfaces. You will probably find it useful to follow the reference and skim the definition of each new class or interface as you encounter them, then come back and finish the behavior description. Later, you can study the characteristics of each Jakarta Faces API in the subsequent chapters.

2.1. Request Processing Lifecycle Scenarios

Each of the scenarios described above has a lifecycle that is composed of a particular set of phases, executed in a particular order. The scenarios are described individually in the following subsections.

2.1.1. Non-Faces Request Generates Faces Response

An application that is processing a non-Faces request may use Jakarta Faces to render a Faces response to that request. In order to accomplish this, the application must perform the common activities that are described in the following sections:

2.1.2. Faces Request Generates Faces Response

The most common lifecycle will be the case where a previous Faces response includes user interface controls that will submit a subsequent request to this web application, utilizing a request URI that is mapped to the Jakarta Faces implementation’s controller, as described in See Servlet Mapping. Because such a request will be initially handled by the Jakarta Faces implementation, the application need not take any special steps—its event listeners, validators, and application actions will be invoked at appropriate times as the standard request processing lifecycle, described in the following diagrams, is invoked.

image

The “Handle Resource Request” box, and its subsequent boxes, are explained in See Resource Handling. The following diagram explains the “Execute and Render Lifecycle” box.

image

The behavior of the individual phases of the request processing lifecycle are described in individual subsections of Standard Request Processing Lifecycle Phases. Note that, at the conclusion of several phases of the request processing lifecycle, common event processing logic (as described in See Common Event Processing) is performed to broadcast any FacesEvents generated by components in the component tree to interested event listeners.

2.1.3. Faces Request Generates Non-Faces Response

Normally, a Jakarta Faces-based application will utilize the Render Response phase of the request processing lifecycle to actually create the response that is sent back to the client. In some circumstances, however, this behavior might not be desirable. For example:

  • A Faces Request needs to be redirected to a different web application resource (via a call to HttpServletResponse.sendRedirect ).

  • A Faces Request causes the generation of a response using some other technology (such as a servlet, or a Jakarta Server Pages page not containing Jakarta Faces components).

  • A Faces Request causes the generation of a response simply by serving up the bytes of a resource, such as an image, a JavaScript file, a CSS file, or an applet

In any of these scenarios, the application will have used the standard mechanisms of the servlet or portlet API to create the response headers and content. It is then necessary to tell the Jakarta Faces implementation that the response has already been created, so that the Render Response phase of the request processing lifecycle should be skipped. This is accomplished by calling the responseComplete() method on the FacesContext instance for the current request, prior to returning from event handlers or application actions.

2.2. Standard Request Processing Lifecycle Phases

The standard phases of the request processing lifecycle are described in the following subsections.

[P1-start-currentPhaseId]The default request lifecycle processing implementation must ensure that the currentPhaseId property of the FacesContext instance for this request is set with the proper PhaseId constant for the current phase as early as possible at the beginning of each phase.[P1-end]

2.2.1. Restore View

[P1-start-restoreView]The Jakarta Faces implementation must perform the following tasks during the Restore View phase of the request processing lifecycle:

  • Call initView() on the ViewHandler . This will set the character encoding properly for this request.

  • Examine the FacesContext instance for the current request. If it already contains a UIViewRoot :

    • Set the locale on this UIViewRoot to the value returned by the getRequestLocale() method on the ExternalContext for this request.

    • Take no further action during this phase, and return. The presence of a UIViewRoot already installed in the FacesContext before the Restore View Phase implementation indicates that the phase should assume the view has already been restored by other means.

  • Derive the viewId according to the following algorithm, or one semantically equivalent to it.

    • Look in the request map for a value under the key jakarta.servlet.include.path_info . If found, let it be the viewId .

    • Call getRequestPathInfo() on the current ExternalContext . If this value is non-null, let this be the viewId .

    • Look in the request map for a value under the key jakarta.servlet.include.servlet_path . If found, let it be the viewId .

    • If none of these steps yields a non- null viewId, throw a FacesException with an appropriate localized message.

  • Determine if this request is a postback or initial request by executing the following algorithm. Find the render-kit-id for the current request by calling calculateRenderKitId() on the Application ’s ViewHandler . Get that RenderKit ’s ResponseStateManager and call its isPostback() method, passing the current FacesContext . If the current request is an attempt by the servlet container to display a servlet error page, do not interpret the request as a postback, even if it is indeed a postback.

  • If the request is a postback, call setProcessingEvents(false) on the current FacesContext . Then call ViewHandler.restoreView() , passing the FacesContext instance for the current request and the view identifier, and returning a UIViewRoot for the restored view. If the return from ViewHandler.restoreView() is null, throw a ViewExpiredException with an appropriate error message. jakarta.faces.application.ViewExpiredException is a FacesException that must be thrown to signal to the application that the expected view was not returned for the view identifier. An application may choose to perform some action based on this exception.

  • Store the restored UIViewRoot in the FacesContext .

  • Call setProcessingEvents(true) on the current FacesContext . __

  • If the request is not a postback, try to obtain the ViewDeclarationLanguage from the ViewHandler , for the current viewId by calling ViewHandler.deriveLogicalViewId() and passing the result to ViewHandler.getViewDeclarationLanguage() . If no such instance can be obtained, call facesContext.renderResponse() . Otherwise, call getViewMetadata() on the ViewDeclarationLanguage instance. If the result is non- null , call createMetadataView() on the ViewMetadata instance. Call ViewMetadata.hasMetadata() , passing the newly created viewRoot . If this method returns false, call facesContext.renderResponse() . If it turns out that the previous call to createViewMetadata() did not create a UIViewRoot instance, call createView() on the ViewHandler .

View Protection
  • Call ViewHandler.getProtectedViewsUnmodifiable() to determine if the view for this viewId is protected. If not, assume the requested view is not protected and take no additional view protection steps. Obtain the value of the value of the request parameter whose name is given by the value of ResponseStateManager.NON_POSTBACK_VIEW_TOKEN_PARAM. If there is no value, throw ProtectedViewException. If the value is present, compare it to the return from ResponseStateManager.getCryptographicallyStrongTokenFromSession(). If the values do not match, throw ProtectedViewException. If the values do match, look for a Referer [sic] request header. If the header is present, use the protected view API to determine if any of the declared protected views match the value of the Referer header. If so, conclude that the previously visited page is also a protected view and it is therefore safe to continue. Otherwise, try to determine if the value of the Referer header corresponds to any of the views in the current web application. If not, throw a ProtectedViewException. If the Origin header is present, additionally perform the same steps as with the Referer header.

  • Call renderResponse() on the FacesContext .

Obtain a reference to the FlowHandler from the Application . Call its clientWindowTransition() method. This ensures that navigation that happened as a result of the renderer for the jakarta.faces.OutcomeTarget component-family is correctly handled with respect to flows. For example, this enables <h:button> to work correctly with flows.

Using Application.publishEvent() , publish a PostAddToViewEvent with the created UIViewRoot as the event source.

In all cases, the implementation must ensure that the restored tree is traversed and the PostRestoreStateEvent is published for every node in the tree.[P1-end]

At the end of this phase, the viewRoot property of the FacesContext instance for the current request will reflect the saved configuration of the view generated by the previous Faces Response, or a new view returned by ViewHandler.createView() for the view identifier.

2.2.2. Apply Request Values

The purpose of the Apply Request Values phase of the request processing lifecycle is to give each component the opportunity to update its current state from the information included in the current request (parameters, headers, cookies, and so on). When the information from the current request has been examined to update the component’s current state, the component is said to have a “local value”.

[P1-start-applyRequestDecode]During the Apply Request Values phase, the Jakarta Faces implementation must call the processDecodes() method of the UIViewRoot of the component tree.[P1-end] This will normally cause the processDecodes() method of each component in the tree to be called recursively, as described in the Javadocs for the UIComponent.processDecodes() method. [P1-start-partialDecode] The processDecodes() method must determine if the current request is a “partial request” by calling FacesContext.getCurrentInstance().getPartialViewContext().isPartialRequest() . If FacesContext.getCurrentInstance().getPartialViewContext().isPartialRequest() returns true , perform the sequence of steps as outlined in See Apply Request Values Partial Processing.[P1-end] Details of the decoding process follow.

During the decoding of request values, some components perform special processing, including:

  • Components that implement ActionSource (such as UICommand ), which recognize that they were activated, will queue an ActionEvent . The event will be delivered at the end of Apply Request Values phase if the immediate property of the component is true , or at the end of Invoke Application phase if it is false .

  • Components that implement EditableValueHolder (such as UIInput ), and whose immediate property is set to true , will cause the conversion and validation processing (including the potential to fire ValueChangeEvent events) that normally happens during Process Validations phase to occur during Apply Request Values phase instead.

As described in See Common Event Processing, the processDecodes() method on the UIViewRoot component at the root of the component tree will have caused any queued events to be broadcast to interested listeners.

At the end of this phase, all EditableValueHolder components in the component tree will have been updated with new submitted values included in this request (or enough data to reproduce incorrect input will have been stored, if there were conversion errors). [P1-start-applyRequestConversion]In addition, conversion and validation will have been performed on EditableValueHolder components whose immediate property is set to true , as described in the UIInput Javadocs. Conversions and validations that failed will have caused messages to be enqueued via calls to the addMessage() method of the FacesContext instance for the current request, and the valid property on the corresponding component(s) will be set to false . [P1-end]

If any of the decode() methods that were invoked, or an event listener that processed a queued event, called responseComplete() on the FacesContext instance for the current request, clear the remaining events from the event queue and terminate lifecycle processing of the current request. [P1-start-applyRequestComplete]If any of the decode() methods that were invoked, or an event listener that processed a queued event, called renderResponse() on the FacesContext instance for the current request, clear the remaining events from the event queue and transfer control to the Render Response phase of the request processing lifecycle. Otherwise, control must proceed to the Process Validations phase.[P1-end]

2.2.2.1. Apply Request Values Partial Processing

[P1-start-apply-partial-processing]Call FacesContext.getPartialViewContext(). Call PartialViewContext.processPartial() passing the FacesContext, PhaseID.APPLY_REQUEST_VALUES as arguments. [P1-end]

2.2.3. Process Validations

As part of the creation of the view for this request, zero or more Validator instances may have been registered for each component. In addition, component classes themselves may implement validation logic in their validate() methods.

[P1-start-validation]During the Process Validations phase of the request processing lifecycle, the Jakarta Faces implementation must call the processValidators() method of the UIViewRoot of the tree.[P1-end] This will normally cause the processValidators() method of each component in the tree to be called recursively, as described in the API reference for the UIComponent.processValidators() method. [P1-start-partialValidate] The processValidators() method must determine if the current request is a “partial request” by calling FacesContext.getCurrentInstance().getPartialViewContext().isPartialRequest() . If FacesContext.getCurrentInstance().getPartialViewContext().isPartialRequest() returns true , perform the sequence of steps as outlined in See Partial Validations Partial Processing.[P1-end] Note that EditableValueHolder components whose immediate property is set to true will have had their conversion and validation processing performed during Apply Request Values phase.

During the processing of validations, events may have been queued by the components and/or Validator s whose validate() method was invoked. As described in See Common Event Processing, the processValidators() method on the UIViewRoot component at the root of the component tree will have caused any queued events to be broadcast to interested listeners.

At the end of this phase, all conversions and configured validations will have been completed. Conversions and Validations that failed will have caused messages to be enqueued via calls to the addMessage() method of the FacesContext instance for the current request, and the valid property on the corresponding components will have been set to false .

If any of the validate() methods that were invoked, or an event listener that processed a queued event, called responseComplete() on the FacesContext instance for the current request, clear the remaining events from the event queue and terminate lifecycle processing of the current request. [P1-start-validationValidate]If any of the validate() methods that were invoked, or an event listener that processed a queued event, called renderResponse() on the FacesContext instance for the current request, clear the remaining events from the event queue and transfer control to the Render Response phase of the request processing lifecycle. Otherwise, control must proceed to the Update Model Values phase.[P1-end]

2.2.3.1. Partial Validations Partial Processing

[P1-start-val-partial-processing]Call FacesContext.getPartialViewContext(). Call PartialViewContext.processPartial() passing the FacesContext, PhaseID.PROCESS_VALIDATIONS as arguments. [P1-end]

2.2.4. Update Model Values

If this phase of the request processing lifecycle is reached, it is assumed that the incoming request is syntactically and semantically valid (according to the validations that were performed), that the local value of every component in the component tree has been updated, and that it is now appropriate to update the application’s model data in preparation for performing any application events that have been enqueued.

[P1-start-updateModel]During the Update Model Values phase, the Jakarta Faces implementation must call the processUpdates() method of the UIViewRoot component of the tree.[P1-end] This will normally cause the processUpdates() method of each component in the tree to be called recursively, as described in the API reference for the UIComponent.processUpdates() method. [P1-start-partialUpdate] The processUpdates() method must determine if the current request is a “partial request” by calling FacesContext.getCurrentInstance().getPartialViewContext().isPartialRequest() . If FacesContext.getCurrentInstance().getPartialViewContext().isPartialRequest() returns true , perform the sequence of steps as outlined in See Update Model Values Partial Processing. [P1-end]The actual model update for a particular component is done in the updateModel() method for that component.

During the processing of model updates, events may have been queued by the components whose updateModel() method was invoked. As described in See Common Event Processing, the processUpdates() method on the UIViewRoot component at the root of the component tree will have caused any queued events to be broadcast to interested listeners.

At the end of this phase, all appropriate model data objects will have had their values updated to match the local value of the corresponding component, and the component local values will have been cleared.

If any of the updateModel() methods that were invoked, or an event listener that processed a queued event, called responseComplete() on the FacesContext instance for the current request, clear the remaining events from the event queue and terminate lifecycle processing of the current request. [P1-start-updateModelComplete]If any of the updateModel() methods that was invoked, or an event listener that processed a queued event, called renderResponse() on the FacesContext instance for the current request, clear the remaining events from the event queue and transfer control to the Render Response phase of the request processing lifecycle. Otherwise, control must proceed to the Invoke Application phase.[P1-end]

2.2.4.1. Update Model Values Partial Processing

[P1-start-upd-partial-processing]Call FacesContext.getPartialViewContext(). Call PartialViewContext.processPartial() passing the FacesContext, PhaseID.UPDATE_MODEL_VALUES as arguments. [P1-end]

2.2.5. Invoke Application

If this phase of the request processing lifecycle is reached, it is assumed that all model updates have been completed, and any remaining event broadcast to the application needs to be performed. [P1-start-invokeApplication]The implementation must ensure that the processApplication() method of the UIViewRoot instance is called.[P1-end] The default behavior of this method will be to broadcast any queued events that specify a phase identifier of PhaseId.INVOKE_APPLICATION . If responseComplete() was called on the FacesContext instance for the current request, clear the remaining events from the event queue and terminate lifecycle processing of the current request. If renderResponse() was called on the FacesContext instance for the current request, clear the remaining events from the event queue.

Advanced applications (or application frameworks) may replace the default ActionListener instance by calling the setActionListener() method on the Application instance for this application. [P1-start-invokeApplicationListener]However, the Jakarta Faces implementation must provide a default ActionListener instance that behaves as described in See ActionListener Property.[P1-end]

2.2.6. Render Response

This phase accomplishes two things:

  1. Causes the response to be rendered to the client

  2. Causes the state of the response to be saved for processing on subsequent requests.

Jakarta Faces supports a range of approaches that Jakarta Faces implementations may utilize in creating the response text that corresponds to the contents of the response view, including:

  • Deriving all of the response content directly from the results of the encoding methods (on either the components or the corresponding renderers) that are called.

  • Interleaving the results of component encoding with content that is dynamically generated by application programming logic.

  • Interleaving the results of component encoding with content that is copied from a static “template” resource.

  • Interleaving the results of component encoding by embedding calls to the encoding methods into a dynamic resource (such as representing the components as custom tags in a Jakarta Server Pages page).

Because of the number of possible options, the mechanism for implementing the Render Response phase cannot be specified precisely. [P1-start-renderResponse]However, all Jakarta Faces implementations of this phase must conform to the following requirements:

  • If it is possible to obtain a ViewDeclarationLanguage instance for the current viewId , from the ViewHandler , its buildView() method must be called. __

  • Publish the jakarta.faces.event.PreRenderViewEvent .

  • Jakarta Faces implementations must provide a default ViewHandler implementation that is capable of handling views written in Jakarta Server Pages as well as views written in the Faces View Declaration Language (VDL). In the case of Jakarta Server Pages, the ViewHandler must perform a RequestDispatcher.forward() call to a web application resource whose context-relative path is equal to the view identifier of the component tree.

  • If all of the response content is being derived from the encoding methods of the component or associated Renderer s, the component tree should be walked in the same depth-first manner as was used in earlier phases to process the component tree, but subject to the additional constraints listed here. Generally this is handled by a call to ViewHandler.renderView() . __

  • If the response content is being interleaved from additional sources and the encoding methods, the components may be selected for rendering in any desired order 1.

  • During the rendering process, additional components may be added to the component tree based on information available to the ViewHandler implementation 2. However, before adding a new component, the ViewHandler implementation must first check for the existence of the corresponding component in the component tree. If the component already exists (perhaps because a previous phase has pre-created one or more components), the existing component’s properties and attributes must be utilized.

  • Under no circumstances should a component be selected for rendering when its parent component, or any of its ancestors in the component tree, has its rendersChildren property set to true. In such cases, the parent or ancestor component must render the content of this child component when the parent or ancestor was selected.

  • If the isRendered() method of a component returns false , the renderer for that component must not generate any markup, and none of its facets or children (if any) should be rendered.

  • It must be possible for the application to programmatically modify the component tree at any time during the request processing lifecycle (except during the rendering of the view) and have the system behave as expected. For example, the following must be permitted. Modification of the view during rendering may lead to undefined results. It must be possible to allow components added by the templating system (such as Jakarta Server Pages) to be removed from the tree before rendering. It must be possible to programmatically add components to the tree and have them render in the proper place in the hierarchy. It must be possible to re-order components in the tree before rendering. These manipulations do require that any components added to the tree have ids that are unique within the scope of the closest parent NamingContainer component. The value of the rendersChildren property is handled as expected, and may be either true or false .

  • If running on a container that supports Servlet 4.0 or later, after any dynamic component manipulations have been completed, any resources that have been added to the UIViewRoot, such as scripts, images, or stylesheets, and any inline images, must be pushed to the client using the Servlet Server Push API. All of the pushes must be started before any of the HTML of the response is rendered to the client.

  • For partial requests, where partial view rendering is required, there must be no content written outside of the view (outside f:view ). Response writing must be disabled. Response writing must be enabled again at the start of encodeBegin.

When each particular component in the component tree is selected for rendering, calls to its encodeXxx() methods must be performed in the manner described in See Component Specialization Methods. For components that implement ValueHolder (such as UIInput and UIOutput ), data conversion must occur as described in the UIOutput Javadocs.

Upon completion of rendering, but before state saving the Jakarta Faces runtime must publish a jakarta.faces.event.PostRenderViewEvent . After doing so the Jakarta Faces runtime must save the completed state using the methods of the class StateManager. This state information must be made accessible on a subsequent request, so that the Restore View can access it.[P1-end] For more on StateManager , see See State Saving Methods.

2.2.6.1. Render Response Partial Processing

[P1-start-render-partial-processing] According to UIViewRoot.encodeChildren() , FacesContext.processPartial(PhaseId.RENDER_RESPONSE) , will be called if and only if the current request is an Ajax request. Take these actions in this case.

On the ExternalContext for the request, call setResponseContentType("text/xml") and addResponseHeader("Cache-control", "no-cache") . Call startDocument() on the PartialResponseWriter .

Call writePreamble(“<?xml version=’1.0’ encoding=’currentEncoding’?>\n”) on the PartialResponseWriter , where encoding is the return from the getCharacterEncoding() on the PartialResponseWriter , or UTF-8 if that method returns null .

If isResetValues() returns true , call getRenderIds() and pass the result to UIViewRoot.resetValues() .

If isRenderAll() returns true and the view root is not an instance of NamingContainer , call startUpdate(PartialResponseWriter.RENDER_ALL_MARKER) on the PartialResponseWriter . For each child of the UIViewRoot , call encodeAll() . Call endUpdate() on the PartialResponseWriter . Render the state using the algorithm described below in See Partial State Rendering, call endDocument() on the PartialResponseWriter and return. If isRenderAll() returns true and this UIViewRoot is a NamingContainer , treat this as a case where isRenderAll() returned false , but use the UIViewRoot itself as the one and only component from which the tree visit must start.

If isRenderAll() returns false , if there are ids to render, visit the subset of components in the tree to be rendered in similar fashion as for other phases, but for each UIComponent in the traversal, call startUpdate(id) on the PartialResponseWriter , where id is the client id of the component. Call encodeAll() on the component, and then endUpdate() on the PartialResponseWriter . If there are no ids to render, this step is un-necessary. After the subset of components (if any) have been rendered, Render the state using the algorithm described below in See Partial State Rendering, call endDocument() on the PartialResponseWriter and return.

Partial State Rendering

This section describes the requirements for rendering the <update> elements pertaining to view state and window id in the case of partial response rendering.

If the view root is marked transient, take no action and return.

Obtain a unique id for the view state, as described in the JavaDocs for the constant field ResponseStateManager.VIEW_STATE_PARAM . Pass this id to a call to startUpdate() on the PartialResponseWriter . Obtain the view state to render by calling getViewState() on the application’s StateManager . Write the state by calling write() on the PartialResponseWriter , passing the state as the argument. Call endUpdate() on the PartialResponseWriter .

If getClientWindow() on the ExternalContext , returns non- null , obtain an id for the <update> element for the window id as described in the JavaDocs for the constant ResponseStateManager.WINDOW_ID_PARAM . Pass this id to a call to startUpdate() on the PartialResponseWriter . Call write() on that same writer, passing the result of calling getId() on the ClientWindow . Call endUpdate() on the PartialResponseWriter .

[P1-end]

2.3. Common Event Processing

For a complete description of the event processing model for Jakarta Server Faces components, see See Event and Listener Model.

During several phases of the request processing lifecycle, as described in See Standard Request Processing Lifecycle Phases, the possibility exists for events to be queued (via a call to the queueEvent() method on the source UIComponent instance, or a call to the queue() method on the FacesEvent instance), which must now be broadcast to interested event listeners. The broadcast is performed as a side effect of calling the appropriate lifecycle management method ( processDecodes() , processValidators() , processUpdates() , or processApplication() ) on the UIViewRoot instance at the root of the current component tree.

[P1-start-eventBroadcast]For each queued event, the broadcast() method of the source UIComponent must be called to broadcast the event to all event listeners who have registered an interest, on this source component for events of the specified type, after which the event is removed from the event queue.[P1-end] See the API reference for the UIComponent.broadcast() method for the detailed functional requirements.

It is also possible for event listeners to cause additional events to be enqueued for processing during the current phase of the request processing lifecycle. [P1-start-eventOrder]Such events must be broadcast in the order they were enqueued, after all originally queued events have been broadcast, before the lifecycle management method returns.[P1-end]

2.4. Common Application Activities

The following subsections describe common activities that may be undertaken by an application that is using Jakarta Faces to process an incoming request and/or create an outgoing response. Their use is described in See Request Processing Lifecycle Scenarios, for each request processing lifecycle scenario in which the activity is relevant.

2.4.1. Acquire Faces Object References

This phase is only required when the request being processed was not submitted from a previous response, and therefore did not initiate the Faces Request Generates Faces Response lifecycle. In order to generate a Faces Response, the application must first acquire references to several objects provided by the Jakarta Faces implementation, as described below.

2.4.1.1. Acquire and Configure Lifecycle Reference

[P1-start-lifeReference]As described in See Lifecycle, the Jakarta Faces implementation must provide an instance of jakarta.faces.lifecycle.Lifecycle that may be utilized to manage the remainder of the request processing lifecycle.[P1-end] An application may acquire a reference to this instance in a portable manner, as follows:

LifecycleFactory lFactory = (LifecycleFactory)
    FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY);
Lifescycle lifecycle =
    lFactory.getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);

It is also legal to specify a different lifecycle identifier as a parameter to the getLifecycle() method, as long as this identifier is recognized and supported by the Jakarta Faces implementation you are using. However, using a non-default lifecycle identifier will generally not be portable to any other Jakarta Faces implementation.

2.4.1.2. Acquire and Configure FacesContext Reference

[P1-start-contextReference]As described in See FacesContext, the Jakarta Faces implementation must provide an instance of jakarta.faces.context.FacesContext to contain all of the per-request state information for a Faces Request or a Faces Response. An application that is processing a Non-Faces Request, but wants to create a Faces Response, must acquire a reference to a FacesContext instance as follows

FacesContextFactory fcFactory = (FacesContextFactory)
    FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);
FacesContext facesContext =
    fcFactory.getFacesContext(context, request, response, lifecycle);

where the context , request , and response objects represent the corresponding instances for the application environment.[P1-end] For example, in a servlet-based application, these would be the ServletContext , HttpServletRequest , and HttpServletResponse instances for the current request.

2.4.2. Create And Configure A New View

When a Faces response is being intially created, or when the application decides it wants to create and configure a new view that will ultimately be rendered, it may follow the steps described below in order to set up the view that will be used. You must start with a reference to a FacesContext instance for the current request.

2.4.2.1. Create A New View

Views are represented by a data structure rooted in an instance of jakarta.faces.component.UIViewRoot, and identified by a view identifier whose meaning depends on the ViewHandler implementation to be used during the Render Response phase of the request processing lifecycle 3. The ViewHandler provides a factory method that may be utilized to construct new component trees, as follows:

String viewId = ... identifier of the desired Tree ...;
ViewHandler viewHandler = application.getViewHandler();
UIViewRoot view = viewHandler.createView(facesContext, viewId);

[P1-start-createViewRoot]The UIViewRoot instance returned by the createView() method must minimally contain a single UIViewRoot provided by the Jakarta Faces implementation, which must encapsulate any implementation-specific component management that is required.[P1-end] Optionally, a Jakarta Faces implementation’s ViewHandler may support the automatic population of the returned UIViewRoot with additional components, perhaps based on some external metadata description.

[P1-start-createView]The caller of ViewHandler.createView() must cause the FacesContext to be populated with the new UIViewRoot. Applications must make sure that it is safe to discard any state saved in the view rooted at the UIViewRoot currently stored in the FacesContext .[P1-end] If Facelets is the page definition language, FacesContext.setViewRoot() must be called before returning from ViewHandler.createView(). Refer to See Default ViewHandler Implementation for more ViewHandler details.

2.4.2.2. Configure the Desired RenderKit

[P1-start-defaultRenderkit]The UIViewRoot instance provided by the ViewHandler , as described in the previous subsection, must automatically be configured to utilize the default jakarta.faces.render.RenderKit implementation provided by the Jakarta Faces implementation, as described in See RenderKit. This RenderKit must support the standard components and Renderer s described later in this specification, to maximize the portability of your application.[P1-end]

However, a different RenderKit instance provided by your Jakarta Faces implementation (or as an add-on library) may be utilized instead, if desired. A reference to this RenderKit instance can be obtained from the standard RenderKitFactory , and then assigned to the UIViewRoot instance created previously, as follows:

String renderKitId = ... identifier of desired RenderKit ...;
RenderKitFactory rkFactory = (RenderKitFactory)
    FactoryFinder.getFactory(FactoryFinder.RENDER_KIT_FACTORY);
RenderKit renderKit = rkFactory.getRenderKit(renderKitId, facesContext);
view.setRenderKitId(renderKitId);

As described in Chapter 8, changing the RenderKit being used changes the set of Renderer s that will actually perform decoding and encoding activities. Because the components themselves store only a rendererType property (a logical identifier of a particular Renderer ), it is thus very easy to switch between RenderKit s, as long as they support renderers with the same renderer types.

[P1-start-calcRenderkitId]The default ViewHandler must call calculateRenderKitId() on itself and set the result into the UIViewRoot ’s renderKitId property.[P1-end] This allows applications that use alternative RenderKit s to dynamically switch on a per-view basis.

2.4.2.3. Configure The View’s Components

At any time, the application can add new components to the view, remove them, or modify the attributes and properties of existing components. For example, a new FooComponent (an implementation of UIComponent ) can be added as a child to the root UIViewRoot in the component tree as follows:

FooComponent component = ... create a FooComponent instance ...;
facesContext.getViewRoot().getChildren().add(component);
2.4.2.4. Store the new View in the FacesContext

[P1-start-setViewRoot]Once the view has been created and configured, the FacesContext instance for this request must be made aware of it by calling setViewRoot() .[P1-end]

2.5. Concepts that impact several lifecycle phases

This section is intended to give the reader a “big picture” perspective on several complex concepts that impact several request processing lifecycle phases.

2.5.1. Value Handling

At a fundamental level, Jakarta Server Faces is a way to get values from the user, into your model tier for processing. The process by which values flow from the user to the model has been documented elsewhere in this spec, but a brief holistic survey comes in handy. The following description assumes the Jakarta Server Pages/HTTP case, and that all components have Renderers.

2.5.1.1. Apply Request Values Phase

The user presses a button that causes a form submit to occur. This causes the state of the form to be sent as name=value pairs in the POST data of the HTTP request. The Jakarta Faces request processing lifecycle is entered, and eventually we come to the Apply Request Values Phase . In this phase, the decode() method for each Renderer for each UIComponent in the view is called. The Renderer takes the value from the request and passes it to the setSubmittedValue() method of the component, which is, of course, an instance of EditableValueHolder . If the component has the " immediate " property set to true , we execute validation immediately after decoding. See below for what happens when we execute validation.

2.5.1.2. Process Validators Phase

processValidators() is called on the root of the view. For each EditableValueHolder in the view, If the “ immediate ” property is not set, we execute validation for each UIInput in the view. Otherwise, validation has already occurred and this phase is a no-op.

2.5.1.3. Executing Validation

Please see the javadocs for UIInput.validate() for more details, but basically, this method gets the submitted value from the component (set during Apply Request Values ), gets the Renderer for the component and calls its getConvertedValue() , passing the submitted value. If a conversion error occurs, it is dealt with as described in the javadocs for that method. Otherwise, all validators attached to the component are asked to validate the converted value. If any validation errors occur, they are dealt with as described in the javadocs for Validator.validate() . The converted value is pushed into the component’s setValue() method, and a ValueChangeEvent is fired if the value has changed.

2.5.1.4. Update Model Values Phase

For each UIInput component in the view, its updateModel() method is called. This method only takes action if a local value was set when validation executed and if the page author configured this component to push its value to the model tier. This phase simply causes the converted local value of the UIInput component to be pushed to the model in the way specified by the page author. Any errors that occur as a result of the attempt to push the value to the model tier are dealt with as described in the javadocs for UIInput.updateModel() .

2.5.2. Localization and Internationalization (L10N/I18N)

Jakarta Server Faces is fully internationalized. The I18N capability in Jakarta Server Faces builds on the I18N concepts offered in the Servlet, Jakarta Server Pages and JSTL specifications. I18N happens at several points in the request processing lifecycle, but it is easiest to explain what goes on by breaking the task down by function.

2.5.2.1. Determining the active Locale

Jakarta Faces has the concept of an active Locale which is used to look up all localized resources. Converters must use this Locale when performing their conversion. This Locale is stored as the value of the locale JavaBeans property on the UIViewRoot of the current FacesContext . The application developer can tell Jakarta Faces what locales the application supports in the applications’ WEB-INF/faces-config.xml file. For example:

<faces-config>
  <application>
    <locale-config>
      <default-locale>en</default-locale>
      <supported-locale>de</supported-locale>
      <supported-locale>fr</supported-locale>
      <supported-locale>es</supported-locale>
    </locale-config>
  </application>

This application’s default locale is en , but it also supports de, fr, and es locales. These elements cause the Application instance to be populated with Locale data. Please see the javadocs for details.

The UIViewRoot ’s Locale is determined and set by the ViewHandler during the execution of the ViewHandler ’s createView() method. [P1-start-locale]This method must cause the active Locale to be determined by looking at the user’s preferences combined with the application’s stated supported locales.[P1-end] Please see the javadocs for details.

The application can call UIViewRoot.setLocale() directly, but it is also possible for the page author to override the UIViewRoot ’s locale by using the locale attribute on the <f:view > tag. [P1-start-localeValue]The value of this attribute must be specified as language[\{-|}country[\{-|}variant]] without the colons, for example " ja_JP_SJIS ". The separators between the segments must be ' - ' or ' _ '.[P1-end]

In all cases where Jakarta Server Pages is utilized, the active Locale is set under “request scope” into the JSTL class jakarta.servlet.jsp.jstl.core.Config , under the key Config.FMT_LOCALE .

To facilitate BCP 47 support, the Locale parsing mentioned above is done only if the JDK Locale.languageForTag method does not return a Locale with a language in it. The additional format of the Locale string is as specified by that method.

2.5.2.2. Determining the Character Encoding

The request and response character encoding are set and interpreted as follows.

On an initial request to a Faces webapp, the request character encoding is left unmodified, relying on the underlying request object (e.g., the servlet or portlet request) to parse request parameter correctly.

[P1-start-setLocale]At the beginning of the render-response phase, the ViewHandler must ensure that the response Locale is set to be that of the UIViewRoot, for example by calling ServletResponse.setLocale() when running in the servlet environment.[P1-end] Setting the response Locale may affect the response character encoding, see the Servlet and Portlet specifications for details.

[P1-start-encoding]At the end of the render-response phase, the ViewHandler must store the response character encoding used by the underlying response object (e.g., the servlet or portlet response) in the session (if and only if a session already exists) under a well known, implementation-dependent key.

On a subsequent postback, before any of the ExternalContext methods for accessing request parameters are invoked, the ViewHandler must examine the Content-Type header to read the charset attribute and use its value to set it as the request encoding for the underlying request object. If the Content-Type header doesn’t contain a charset attribute, the encoding previously stored in the session (if and only if a session already exists), must be used to set the encoding for the underlying request object. If no character encoding is found, the request encoding must be left unmodified.[P1-end]

The above algorithm allows an application to use the mechanisms of the underlying technologies to adjust both the request and response encoding in an application-specific manner, for instance using the page directive with a fixed character encoding defined in the contentType attribute in a Jakarta Server Pages page, see the Servlet, Portlet and Jakarta Server Pages specifications for details. Note, though, that the character encoding rules prior to Servlet 2.4 and Jakarta Server Pages 2.0 are imprecise and special care must be taken for portability between containers.

2.5.2.3. Localized Text

There is no direct support for this in the API, but the Jakarta Server Pages layer provides a convenience tag that converts a ResourceBundle into a java.util.Map and stores it in the scoped namespace so all may get to it. This section describes how resources displayed to the end user may be localized. This includes images, labels, button text, tooltips, alt text, etc.

Since most Jakarta Faces components allow pulling their display value from the model tier, it is easy to do the localization at the model tier level. As a convenience, Jakarta Faces provides the <f:loadBundle> tag, which takes a ResourceBundle and loads it into a Map , which is then stored in the scoped namespace in request scope, thus making its messages available using the same mechanism for accessing data in the model tier. For example:

<f:loadBundle basename=com.foo.industryMessages.chemical
              var=messages />
<h:outputText value=#\{messages.benzene} />

This must cause the ResourceBundle named com.foo.industryMessages.chemical to be loaded as a Map into the request scope under the key messages . Localized content can then be pulled out of it using the normal value expression syntax.

2.5.2.4. Localized Application Messages

This section describes how Jakarta Faces handles localized error and informational messages that occur as a result of conversion, validation, or other application actions during the request processing lifecycle. The Jakarta Faces class jakarta.faces.application.FacesMessage is provided to encapsulate summary, detail, and severity information for a message. [P1-start-bundle]A Jakarta Faces implementation must provide a jakarta.faces.Messages ResourceBundle containing all of the necessary keys for the standard messages. The required keys (and a non-normative indication of the intended message text) are as follows:

  • jakarta.faces.component.UIInput.CONVERSION — {0}: Conversion error occurred

  • jakarta.faces.component.UIInput.REQUIRED — {0}: Validation Error: Value is required

  • jakarta.faces.component.UIInput.UPDATE — {0}: An error occurred when processing your submitted information

  • jakarta.faces.component.UISelectOne.INVALID — {0}: Validation Error: Value is not valid

  • jakarta.faces.component.UISelectMany.INVALID — {0}: Validation Error: Value is not valid

  • jakarta.faces.converter.BigDecimalConverter.DECIMAL={2}: ''{0}'' must be a signed decimal number.

  • jakarta.faces.converter.BigDecimalConverter.DECIMAL_detail={2}: ''{0}'' must be a signed decimal number consisting of zero or more digits, that may be followed by a decimal point and fraction. Example: {1}

  • jakarta.faces.converter.BigIntegerConverter.BIGINTEGER={2}: ''{0}'' must be a number consisting of one or more digits.

  • jakarta.faces.converter.BigIntegerConverter.BIGINTEGER_detail={2}: ''{0}'' must be a number consisting of one or more digits. Example: {1}

  • jakarta.faces.converter.BooleanConverter.BOOLEAN={1}: ''{0}'' must be 'true' or 'false'.

  • jakarta.faces.converter.BooleanConverter.BOOLEAN_detail={1}: ''{0}'' must be 'true' or 'false'. Any value other than 'true' will evaluate to 'false'.

  • jakarta.faces.converter.ByteConverter.BYTE={2}: ''{0}'' must be a number between -128 and 127.

  • jakarta.faces.converter.ByteConverter.BYTE_detail={2}: ''{0}'' must be a number between -128 and 127. Example: {1}

  • jakarta.faces.converter.CharacterConverter.CHARACTER={1}: ''{0}'' must be a valid character.

  • jakarta.faces.converter.CharacterConverter.CHARACTER_detail={1}: ''{0}'' must be a valid ASCII character.

  • jakarta.faces.converter.DateTimeConverter.DATE={2}: ''{0}'' could not be understood as a date.

  • jakarta.faces.converter.DateTimeConverter.DATE_detail={2}: ''{0}'' could not be understood as a date. Example: {1}

  • jakarta.faces.converter.DateTimeConverter.TIME={2}: ''{0}'' could not be understood as a time.

  • jakarta.faces.converter.DateTimeConverter.TIME_detail={2}: ''{0}'' could not be understood as a time. Example: {1}

  • jakarta.faces.converter.DateTimeConverter.DATETIME={2}: ''{0}'' could not be understood as a date and time.

  • jakarta.faces.converter.DateTimeConverter.DATETIME_detail={2}: ''{0}'' could not be understood as a date and time. Example: {1}

  • jakarta.faces.converter.DateTimeConverter.PATTERN_TYPE={1}: A 'pattern' or 'type' attribute must be specified to convert the value ''{0}''.

  • jakarta.faces.converter.DoubleConverter.DOUBLE={2}: ''{0}'' must be a number consisting of one or more digits.

  • jakarta.faces.converter.DoubleConverter.DOUBLE_detail={2}: ''{0}'' must be a number between 4.9E-324 and 1.7976931348623157E308 Example: {1}

  • jakarta.faces.converter.EnumConverter.ENUM={2}: ''{0}'' must be convertible to an enum.

  • jakarta.faces.converter.EnumConverter.ENUM_detail={2}: ''{0}'' must be convertible to an enum from the enum that contains the constant ''{1}''.

  • jakarta.faces.converter.EnumConverter.ENUM_NO_CLASS={1}: ''{0}'' must be convertible to an enum from the enum, but no enum class provided.

  • jakarta.faces.converter.EnumConverter.ENUM_NO_CLASS_detail={1}: ''{0}'' must be convertible to an enum from the enum, but no enum class provided.

  • jakarta.faces.converter.FloatConverter.FLOAT={2}: ''{0}'' must be a number consisting of one or more digits.

  • jakarta.faces.converter.FloatConverter.FLOAT_detail={2}: ''{0}'' must be a number between 1.4E-45 and 3.4028235E38 Example: {1}

  • jakarta.faces.converter.IntegerConverter.INTEGER={2}: ''{0}'' must be a number consisting of one or more digits.

  • jakarta.faces.converter.IntegerConverter.INTEGER_detail={2}: ''{0}'' must be a number between -2147483648 and 2147483647 Example: {1}

  • jakarta.faces.converter.LongConverter.LONG={2}: ''{0}'' must be a number consisting of one or more digits.

  • jakarta.faces.converter.LongConverter.LONG_detail={2}: ''{0}'' must be a number between -9223372036854775808 to 9223372036854775807 Example: {1}

  • jakarta.faces.converter.NumberConverter.CURRENCY={2}: ''{0}'' could not be understood as a currency value.

  • jakarta.faces.converter.NumberConverter.CURRENCY_detail={2}: ''{0}'' could not be understood as a currency value. Example: {1}

  • jakarta.faces.converter.NumberConverter.PERCENT={2}: ''{0}'' could not be understood as a percentage.

  • jakarta.faces.converter.NumberConverter.PERCENT_detail={2}: ''{0}'' could not be understood as a percentage. Example: {1}

  • jakarta.faces.converter.NumberConverter.NUMBER={2}: ''{0}'' is not a number.

  • jakarta.faces.converter.NumberConverter.NUMBER_detail={2}: ''{0}'' is not a number. Example: {1}

  • jakarta.faces.converter.NumberConverter.PATTERN={2}: ''{0}'' is not a number pattern.

  • jakarta.faces.converter.NumberConverter.PATTERN_detail={2}: ''{0}'' is not a number pattern. Example: {1}

  • jakarta.faces.converter.ShortConverter.SHORT={2}: ''{0}'' must be a number consisting of one or more digits.

  • jakarta.faces.converter.ShortConverter.SHORT_detail={2}: ''{0}'' must be a number between -32768 and 32767 Example: {1}

  • jakarta.faces.converter.STRING={1}: Could not convert ''{0}'' to a string.

  • jakarta.faces.validator.BeanValidator.MESSAGE — {0}

  • jakarta.faces.validator.DoubleRangeValidator.MAXIMUM — {1}: Validation Error: Value is greater than allowable maximum of ‘’{0}’’

  • jakarta.faces.validator.DoubleRangeValidator.MINIMUM — {1}: Validation Error: Value is less than allowable minimum of ‘’{0}’’

  • jakarta.faces.validator.DoubleRangeValidator.NOT_IN_RANGE — {2}: Validation Error: Specified attribute is not between the expected values of {0} and {1}.

  • jakarta.faces.validator.DoubleRangeValidator.TYPE — {0}: Validation Error: Value is not of the correct type

  • jakarta.faces.validator.LengthValidator.MAXIMUM — {1}: Validation Error: Length is greater than allowable maximum of ‘’{0}’’

  • jakarta.faces.validator.LengthValidator.MINIMUM — {1}: Validation Error: Length is less than allowable minimum of ‘’{0}’’

  • jakarta.faces.validator.LongRangeValidator.MAXIMUM — {1}: Validation Error: Value is greater than allowable maximum of ‘’{0}’’

  • jakarta.faces.validator.LongRangeValidator.MINIMUM — {1}: Validation Error Value is less than allowable minimum of ‘’{0}’’

  • jakarta.faces.validator.LongRangeValidator.NOT_IN_RANGE={2}: Validation Error: Specified attribute is not between the expected values of {0} and {1}.

  • jakarta.faces.validator.LongRangeValidator.TYPE — {0}: Validation Error: Value is not of the correct type

The following message keys are deprecated:

  • jakarta.faces.validator.NOT_IN_RANGE — Specified attribute is not between the expected values of {0} and {1}[P1-end]

A Jakarta Faces application may provide its own messages, or overrides to the standard messages by supplying a <message-bundle> element to in the application configuration resources. Since the ResourceBundle provided in the Java platform has no notion of summary or detail, Jakarta Faces adopts the policy that ResourceBundle key for the message looks up the message summary. The detail is stored under the same key as the summary, with _detail appended. [P1-start-bundleKey]These ResourceBundle keys must be used to look up the necessary values to create a localized FacesMessage instance. Note that the value of the summary and detail keys in the ResourceBundle may contain parameter substitution tokens, which must be substituted with the appropriate values using java.text.MessageFormat .[P1-end] Replace the last parameter substitution token shown in the messages above with the input component’s label attribute. For example, {1} for “DoubleRangeValidator.MAXIMUM”, {2} for “ShortConverter.SHORT”. The label attribute is a generic attribute. Please see See Generic Attributes and See Standard HTML RenderKit Implementation for more information on these attributes. If the input component’s label attribute is not specified, use the component’s client identifier.

These messages can be displayed in the page using the UIMessage and UIMessages components and their corresponding tags, <h:message> and <h:messages>.

[P1-start-facesMessage]The following algorithm must be used to create a FacesMessage instance given a message key.

  • Call getMessageBundle() on the Application instance for this web application, to determine if the application has defined a resource bundle name. If so, load that ResourceBundle and look for the message there.

  • If not there, look in the jakarta.faces.Messages resource bundle.

  • In either case, if a message is found, use the above conventions to create a FacesMessage instance.[P1-end]

2.5.3. State Management

Jakarta Server Faces introduces a powerful and flexible system for saving and restoring the state of the view between requests to the server. It is useful to describe state management from several viewpoints. For the page author, state management happens transparently. For the app assembler, state management can be configured to save the state in the client or on the server by setting the ServletContext InitParameter named jakarta.faces.STATE_SAVING_METHOD to either client or server . The value of this parameter directs the state management decisions made by the implementation.

2.5.3.1. State Management Considerations for the Custom Component Author

Since the component developer cannot know what the state saving method will be at runtime, they must be aware of state management. As shown in See The jakarta.faces.component package, all Jakarta Faces components implement the StateHolder interface. As a consequence the standard components provide implementations of PartialStateHolder to suit their needs. [P1-start-componentStateHolder]A custom component that extends UIComponent directly, and does not extend any of the standard components, must implement PartialStateHolder (or its older super-interface, StateHolder ), manually. The helper class StateHelper exists to simplify this process for the custom component author. [P1-end]Please see See PartialStateHolder or See StateHolder for details.

A custom component that does extend from one of the standard components and maintains its own state, in addition to the state maintained by the superclass must take special care to implement StateHolder or PartialStateHolder correctly. [P1-start-saveState]Notably, calls to saveState() must not alter the state in any way.[P1-end] The subclass is responsible for saving and restoring the state of the superclass. Consider this example. My custom component represents a “slider” ui widget. As such, it needs to keep track of the maximum value, minimum value, and current values as part of its state.

public class Slider extends UISelectOne {
  protected Integer min = null;
  protected Integer max = null;
  protected Integer cur = null;

  // ... details omitted
  public Object saveState(FacesContext context) {
    Object values[] = new Object[4];
    values[0] = super.saveState(context);
    values[1] = min;
    values[2] = max;
    values[3] = cur;
  }

  public void restoreState(FacesContext context, Object state) {
    Object values[] = (Object {}) state; // guaranteed to succeed
    super.restoreState(context, values[0]);
    min = (Integer) values[1];
    max = (Integer) values[2];
    cur = (Integer) values[3];
  }

Note that we call super.saveState() and super.restoreState() as appropriate. This is absolutely vital! Failing to do this will prevent the component from working.

2.5.3.2. State Management Considerations for the Jakarta Faces Implementor

The intent of the state management facility is to make life easier for the page author, app assembler, and component author. However, the complexity has to live somewhere, and the Jakarta Faces implementor is the lucky role. Here is an overview of the key players. Please see the javadocs for each individual class for more information.

Key Players in State Management
  • StateHelper the helper class that defines a Map -like contract that makes it easier for components to implement PartialStateHolder .

  • ViewHandler the entry point to the state management system. Uses a helper class, StateManager , to do the actual work. In the Jakarta Server Pages case, delegates to the tag handler for the <f:view> tag for some functionality.

  • StateManager abstraction for the hard work of state saving. Uses a helper class, ResponseStateManager , for the rendering technology specific decisions.

  • ResponseStateManager abstraction for rendering technology specific state management decisions.

  • UIComponent directs process of saving and restoring individual component state.

2.5.4. Resource Handling

This section only applies to pages written using Facelets. See Resource Handling is the starting point for the normative specification for Resource Handling. This section gives a non-normative overview of the feature. The following steps walk through the points in the lifecycle where this feature is encountered. Consider a Faces web application that contains resources that have been packaged into the application as specified in See Packaging Resources. Assume each page in the application includes references to resources, specifically scripts and stylesheets. The first diagram in this chapter is helpful in understanding this example.

Consider an initial request to the application.

  • The ViewHandler calls ViewDeclarationLanguage.buildView() . This ultimately causes the processEvent() method for the jakarta.faces.resource.Script and jakarta.faces.resource.Stylesheet renderers (which implement ComponentSystemEventListener) to be called after each component that declares them as their renderer is added to the view. This method is specified to take actions that cause the resource to be rendered at the correct part in the page based on user-specified or application invariant rules. Here’s how it works.

  • Every UIComponent instance in a view is created with a call to some variant of Application.createComponent() . The specification for this method now includes some annotation processing requirements. If the component or its renderer has an @ListenerFor or @ListenersFor annotation, and the Script and Stylesheet renderers must, the component or its renderer are added as a component scoped listener for the appropriate event. In the case of Script and Stylesheet renderers, they must listen for the PostAddToViewEvent .

  • When the processEvent() method is called on a Script or Stylesheet renderer, the renderer takes the specified action to move the component to the proper point in the tree based on what kind of resource it is, and on what hints the page author has declared on the component in the view.

  • The ViewHandler calls ViewDeclarationLanguage.renderView() . The view is traversed as normal and because the components with Script and Stylesheet renderers have already been reparented to the proper place in the view, the normal renderering causes the resource to be encoded as described in RequestProcessingLifecycle.adoc#a842,See Rendering Resources>>.

The browser then parses the completely rendered page and proceeds to issue subsequent requests for the resources included in the page.

Now consider a request from the browser for one of those resources included in the page.

  • The request comes back to the Faces server. The FacesServlet is specified to call ResourceHandler.isResourceRequest() as shown in the diagram in See Faces Request Generates Faces Response. In this case, the method returns true . The FacesServlet is specified to call ResourceHandler.handleResourceRequest() to serve up the bytes of the resource.

2.5.5. View Parameters

This section only applies to pages written using Facelets. The normative specification for this feature is spread out across several places, including the View Declaration Language Documentation for the <f:metadata> element, the javadocs for the UIViewParameter , ViewHandler , and ViewDeclarationLanguage classes, and the spec language requirements for the default NavigationHandler and the Request Processing Lifecycle. This leads to a very diffuse field of specification requirements. To aid in understanding the feature, this section provides a non-normative overview of the feature. The following steps walk through the points in the lifecycle where this feature is encountered. Consider a web application that uses this feature exclusively on every page. Therefore every page has the following features in common.

  • Every page has an <f:metadata> tag, with at least one <f:viewParameter> element within it.

  • Every page has at least one <h:link> or < h:button> with the appropriate parameters nested within it.

  • No other kind of navigation components are used in the application.

Consider an initial request to the application.

  • As specified in section See Restore View, the restore view phase of the request processing lifecycle detects that this is an initial request and tries to obtain the ViewDeclarationLanguage instance from the ViewHandler for this viewId . Because every page in the app is written in Facelets, there is a ViewDeclarationLanguage instance. Restore view phase calls ViewDeclarationLanguage.getViewMetadata() . Because every view in this particular app does have <f:metadata> on every page, this method returns a ViewMetadata instance. Restore view phase calls MetaData.createMetadataView() . This method creates a UIViewRoot containing only children declared in the <f:metadata> element. Restore view phase calls ViewMetadata.getViewParameters() . Because every <f:metadata> in the app has at least one <f:viewParameter> element within it, this method returns a non empty Collection<UIViewParameter>. Restore view phase uses this fact to decide that the lifecycle must not skip straight to render response, as is the normal action taken on initial requests.

  • The remaining phases of the request processing lifecycle execute: apply request values, process validations, update model values, invoke application, and finally render response. Because the view only contains UIViewParameter children, only these children are traversed during the lifecycle, but because this is an initial request, with no query parameters, none of these compnents take any action during the lifecycle.

  • Because the pages exclusively use <h:link> and <h:button> for their navigation, the renderers for these components are called during the rendering of the page. As specified in the renderkit docs for the renderers for those components, markup is rendered that causes the browser to issue a GET request with query parameters.

Consider when the user clicks on a link in the application. The browser issues a GET request with query parameters

  • Restore view phase takes the same action as in the previously explained request. Because this is a GET request, no state is restored from the previous request.

  • Because this is a request with query parameters, the UIViewParameter children do take action when they are traversed during the normal lifecycle, reading values during the apply request values phase, doing conversion and processing validators attached to the <f:viewParam> elements, if any, and updating models during the update model values phase. Because there are only <h:link> and <h:button> navigation elements in the page, no action action will happen during the invoke application phase. The response is re-rendered as normal. In such an application, the only navigation to a new page happens by virtue of the browser issuing a GET request to a different viewId.

2.5.6. Bookmarkability

Jakarta Faces has a bookmarking capability with the use of two Standard HTML RenderKit additions.

Provided is a component (UIOutcomeTarget) that provides properties that are used to produce a hyperlink at render time. The component can appear in the form of a button or a link. This feature introduces a concept known as “preemptive navigation”, which means the target URL is determined at Render Response time - before the user has activated the component. This feature allows the user to leverage the navigation model while also providing the ability to generate bookmarkable non-faces requests.

2.5.7. Jakarta Bean Validation

Jakarta Faces supports Jakarta Bean Validation. [p1-beanValidationRequired]A Jakarta Faces implementation must support Jakarta Bean Validation if the environment in which the Jakarta Faces runtime is included requires Jakarta Bean Validation. Currently the only such environment is when Jakarta Faces is included in a Jakarta EE runtime.[p1-end]

A detailed description of the usage of Jakarta Bean Validation with Jakarta Faces is beyond the scope of this section, but this section will provide a brief overview of the feature, touching on the points of interest to a spec implementor. Consider a simple web application that has one page, written in Facelets, that has several text fields inside of a form. This application is running in a Jakarta Faces runtime in an environment that does require Jakarta Bean Validation, and therefore this feature is available. Assume that every text field is bound to a managed bean property that has at least one Jakarta Bean Validation constraint annotation attached to it.

During the render response phase that always precedes a postback, due to the specification requirements in See Validation Registration, every UIInput in this application has an instance of Validator with id jakarta.faces.Bean attached to it.

During the process validations phase, due to the specification for the validate() method of this Validator , Bean Validation is invoked automatically, for the user specified validation constraints, whenever such components are normally validated. The jakarta.faces.Bean standard validator also ensures that every ConstraintViolation that resulted in attempting to validate the model data is wrapped in a FacesMessage and added to the FacesContext as normal with every other kind of validator.

2.5.8. Ajax

Jakarta Faces supports Ajax. The specification contains a JavaScript library for performing basic Ajax operations. The library helps define a standard way of sending an Ajax request, and processing an Ajax response, since these are problem areas for component compatibility. The specification provides two ways of adding Ajax to Jakarta Faces web applications. Page authors may use the JavaScript library directly in their pages by attaching the Ajax request call to a Jakarta Faces component via a JavaScript event (such as onclick). They may also take a more declarative approach and use a core Facelets tag (<f:ajax/>) that they can nest within Jakarta Faces components to “Ajaxify” them. It is also possible to “Ajaxify” regions of a page by “wrapping” the tag around component groups.

The server side aspects of Jakarta Faces Ajax frameworks work with the standard Jakarta Faces lifecycle. In addition to providing a standard page authoring experience, the specification also standardizes the server side processing of Ajax requests. Selected components in a Jakarta Faces view can be processed (known as partial processing) and selected components can be rendered to the client (known as partial rendering).

2.5.9. Component Behaviors

The Jakarta Faces specification contains a type of attached object known as component behaviors. Component behaviors play a similar role to converters and validators in that they are attached to a component instance in order to enhance the component with additional functionality not defined by the component itself. While converters and validators are currently limited to the server-side request processing lifecycle, component behaviors have impact that extends to the client, within the scope of a particular instance component in a view. In particular, the ClientBehavior interface defines a contract for behaviors that can enhance a component’s rendered content with behavior-defined "scripts". These scripts are executed on the client in response to end user interaction, but can also trigger postbacks back into the Jakarta Faces request processing lifecycle.

The usage pattern for client behaviors is as follows:

  • The page author attaches a client behavior to a component, typically by specifying a behavior tag as a child of a component tag.

  • When attaching a client behavior to a component, the page author identifies the name of a client "event" to attach to. The set of valid events are defined by the component.

  • At render time, the component (or renderer) retrieves the client behavior and asks it for its script.

  • The component (or renderer) renders this script at the appropriate location in its generated content (eg. typically in a DOM event handler).

  • When the end user interacts with the component’s content in the browser, the behavior-defined script is executed in response to the page author-specified event.

  • The script provides some client-side interaction, for example, hiding or showing content or validating input on the client, and possibly posts back to the server.

The first client behavior provided by the Jakarta Faces specification is the AjaxBehavior . This behavior is exposed to a page author as a Facelets <f:ajax> tag, which can be embedded within any of the standard HTML components as follows:

<h:commandButton>
  <f:ajax event="mouseover"/>
</h:commandButton>

When activated in response to end user activity, the <f:ajax> client behavior generates an Ajax request back into the Jakarta Faces request processing lifecycle.

The component behavior framework is extensible and allows developers to define custom behaviors and also allows component authors to enhance custom components to work with behaviors.

2.5.10. System Events

System Events are normatively specified in See System Events. This section provides an overview of this feature as it relates to the lifecycle.

System events expand on the idea of lifecycle PhaseEvent s. With PhaseEvent s, it is possible to have application scoped PhaseListeners that are given the opportunity to act on the system before and after each phase in the lifecycle. System events provide a much more fine grained insight into the system, allowing application or component scoped listeners to be notified of a variety of kinds of events. The set of events supported in the core specification is given in See Event Classes. To accomodate extensibility, users may define their own kinds of events.

The system event feature is a simple publish/subscribe event model. There is no event queue, events are published immediately, and always with a call to Application.publishEvent() . There are several ways to declare interest in a particular kind of event.

  • Call Application.subscribeToEvent() to add an application scoped listener.

  • Call UIComponent.subscribeToEvent() to add a component scoped listener.

  • Use the <f:event> tag to declare a component scoped listener.

  • Use the @ListenerFor or @ListenersFor annotation. The scope of the listener is determined by the code that processes the annotation.

  • Use the <system-event-listener> element in an application configuration resource to add an application scoped listener.

This feature is conceptually related to the lifecycle because there are calls to Application.publishEvent() sprinkled throughout the code that gets executed when the lifecycle runs.

2.6. Resource Handling

As shown in the diagram in See Faces Request Generates Faces Response, [P1-start isResourceRequest rules] the Jakarta Faces run-time must determine if the current Faces Request is a Faces Resource Request or a View Request . This must be accomplished by calling Application.getResourceHandler().isResourceRequest() . [P1-end] Most of the normative specification for resource handling is contained in the Javadocs for ResourceHandler and its related classes. This section contains the specification for resource handling that fits best in prose, rather than in Javadocs.

2.6.1. Packaging Resources

ResourceHandler defines a path based packaging convention for resources. The default implementation of ResourceHandler must support packaging resources in the web application root or in the classpath, according to the following specification.Other implementations of ResourceHandler are free to package resources however they like.

2.6.1.1. Packaging Resources into the Web Application Root

[P1-start web app packaging ] The default implementation must support packaging resources in the web application root under the path

resources/<resourceIdentifier>

relative to the web app root. Resources packaged into the web app root must be accessed using the getResource*() methods on ExternalContext. [P1-end]

2.6.1.2. Packaging Resources into the Classpath

[P1-start classpath packaging ]For the default implementation, resources packaged in the classpath must reside under the JAR entry name:

META-INF/resources/<resourceIdentifier>

Resources packaged into the classpath must be accessed using the getResource*() methods of the ClassLoader obtained by calling the getContextClassLoader() method of the curreth Thread .[P1-end]

2.6.1.3. Resource Identifiers

<resourceIdentifier> consists of several segments, specified as follows.

[P1-start requirements for something to be considered a valid resourceIdentifier]

[localePrefix/][libraryName/][libraryVersion/]resourceName[/resourceVersion]

The run-time must enforce the following rules to consider a <resourceIdentifier> valid. A <resourceIdentifier> that does not follow these rules must not be considered valid and must be ignored silently.

  • The set of characters that are valid for use in the localePrefix , libraryName , libraryVerison , resourceName and resourceVersion segments of the resource identifier is specififed as XML NameChar excluding the path separator and ‘:’ characters. The specification for XML NameChar may be seen at http://www.w3.org/TR/REC-xml/#NT-NameChar .

  • A further restriction applies to libraryName . A libraryName must not be an underscore separated sequence of non-negative integers or a locale string. More rigorously, a libraryName must not match either of the following regular expressions:

    [0-9]+(_[0-9]+)*
    [A-Za-z]{2}(_[A-Za-z]{2}(_[A-Za-z]+)*)?
  • Segments in square brackets [] are optional.

  • The segments must appear in the order shown above.

  • If libraryVersion is present, it must be preceded by libraryName.

  • If libraryVersion is present, any leaf files under libraryName must be ignored.

  • If resourceVersion is present, it must be preceded by resourceName.

  • There must be a ’ / ’ between adjacent segments in a <resourceIdentifier>

  • If libraryVersion or resourceVersion are present, both must be a ’ _ ’ separated list of integers, neither starting nor ending with ’ _ ’

If resourceVersion is present, it must be a version number in the same format as libraryVersion . An optional “file extension” may be used with the resourceVersion. If “file extension” is used, a “.” character, followed by a “file extension” must be appended to the version number. See the following table for an example.

[P1-end]

The following examples illustrate the nine valid combinations of the above resource identifier segments.

localePrefx

[optional]

libraryName

[optional]

library

Version [optional]

resourceName

[required]

resource

Version [optional]

Description

actual resourceIdentifier

__

__  

__

duke.gif

__

A non-localized, non-versioned image resource called " duke.gif ", not in a library

duke.gif

__

corporate

__

duke.gif

__

A non-localized, non-versioned image resource called " duke.gif " in a library called " corporate "

corporate/duke.gif

__

corporate

2_3

duke.gif

__

A non-localized, non-versioned image resource called " duke.gif ", in version 2_3 of the " corporate " library

corporate/2_3/duke.gif

__

basic

2_3

script.js

1_3_4.js

A non-localized, version 1.3.4 script resource called " script.js ", in versioned 2_3

library called " basic ".

basic/2_3/script.js/1_3_4.js

de

__

__

header.css

__

A non-versioned style resource called " header.css" localized for locale " de "

de/header.css

de_AT

__

__

footer.css

1_4_2.css

Version 1_4_2 of style resource " footer.css ", localized for locale " de_AT "

de_AT/footer.css/1_4_2.css

zh

extraFancy

__

menu-bar.css

2_4.css

Version 2_4 of style resource called, " menu-bar.css " in non-versioned library, " extraFancy ", localized for locale " zh "

zh/extraFancy/menu-bar.css/2_4.css

ja

mild

0_1

ajaxTransaction.js

__

Non-versioned script resource called, " ajaxTransaction.js ", in version 0_1 of library called " mild ", localized for locale " ja "

ja/mild/0_1/ajaxTransaction.js

de_ch

grassy

1_0

bg.png

1_0.png

Version 1_0 of image resource called " bg.png ", in version 1_0 of library called " grassy " localized for locale " de_ch "

de_ch/grassy/1_0/bg.png/1_0.png

2.6.1.4. Libraries of Localized and Versioned Resources

An important feature of the resource handler is the ability for resources to be localized, versioned, and collected into libraries. The localization and versioning scheme is completely hidden behind the API of ResourceHandler and Resource and is not exposed in any way to the Jakarta Faces run-time.

[P1-start resource versioning] The default implementation of ResourceHandler.createResource() , for all variants of that method, must implement the following to discover which actual resource will be encapsulated within the returned Resource instance. An implementation may perform caching of the resource metadata to improve performance if the ProjectStage is ProjectStage.Production .

Using the resourceName and libraryName arguments to createResource() , and the resource packaging scheme specified in See Packaging Resources into the Web Application Root, See Packaging Resources into the Classpath, and See Resource Identifiers, discover the file or entry that contains the bytes of the resource. If there are multiple versions of the same library, and libraryVersion is not specified, the library with the highest version is chosen. If there are multiple versions of the same resource, and resourceVersion is not specified, the resource with the highest version is chosen. The algorithm is specified in pseudocode.

function createResource(resourceName, libraryName) {
    var resource = null;
    var resourceId = null;
    for (var contract : getLibraryContracts()) {
        resourceId = deriveResourceIdConsideringResourceLoaders(contract,
                resourceName, libraryName)
        if (null != resourceId) {
            resource = create the resource using the resourceId;
            return resource;
        }
    }

    // try without a contract
    resourceId = deriveResourceIdConsideringResourceLoaders(null,
            resourceName, libraryName)
    if (null != resourceId) {
        resource = create the resource using the resourceId;
    }
    return resource;
}

function deriveResourceIdConsideringResourceLoaders(contract,
        resourceName, libraryName) {
    var prefix = web app root resource prefix;
    var resourceLoader = web app resource loader;
    // these are shorthand for the prefix and resource loading
    // facility specified in Section 2.6.1.1. They are
    // not actual API per se.
    var resourceId = deriveResourceIdConsideringLocalePrefix(contract,
            prefix, resourceLoader, resourceName, libraryName);

    if (null == resourceId) {
        prefix = classpath resource prefix;
        resourceLoader = classpath resource loader;
        // these are shorthand for the prefix and resource
        // loading facility specified in Section 2.6.1.2. They are
        // not actual API per se.
        resourceId = deriveResourceIdConsideringLocalePrefix(contract,
                prefix, resourceLoader, resourceName, libraryName);
    }
    return resourceId;
}

function deriveResourceIdConsideringLocalePrefix(contract, prefix,
        resourceLoader, resourceName, libraryName) {
    var localePrefix = getLocalePrefix();
    var result = deriveResourceId(contract, prefix, resourceLoader,
            resourceName, libraryName, localePrefix);
    // If the application has been configured to have a localePrefix,
    // and the resource is not found, try to find it again,
    // without the localePrefix.
    if (null == result && null != localePrefix) {
        result = deriveResourceId(contract, prefix, resourceLoader,
                resourceName, libraryName, null);
    }
    return result;
}

function deriveResourceId(contract, prefix, resourceLoader,
        resourceName, libraryName, localePrefix) {
    var resourceVersion = null;
    var libraryVersion = null;
    var resourceId;
    if (null != localePrefix) {
        prefix = localePrefix + '/' + prefix;
    }
    if (null != contract) {
        prefix = contract + '/' + prefix;
    }

    if (null != libraryName) {
        // actual argument is
        // resourcesInContractInJar/resources/resourcesInContractInJar
        var libraryPaths = resourceLoader.getResourcePaths(
                prefix + '/' + libraryName);

        if (null != libraryPaths && !libraryPaths.isEmpty()) {
            libraryVersion = // execute the comment
            // Look in the libraryPaths for versioned libraries.
            // If one or more versioned libraries are found, take
            // the one with the highest version number as the value
            // of libraryVersion. If no versioned libraries
            // are found, let libraryVersion remain null.
        }
        if (null != libraryVersion) {
            libraryName = libraryName + '/' + libraryVersion;
        }
        var resourcePaths = resourceLoader.getResourcePaths(
            prefix + '/' + libraryName + '/' + resourceName);
        if (null != resourcePaths && !resourcePaths.isEmpty()) {
            resourceVersion = // execute the comment +
            // Look in the resourcePaths for versioned resources.
            // If one or more versioned resources are found, take
            // the one with the “highest� version number as the value
            // of resourceVersion. If no versioned libraries
            // are found, let resourceVersion remain null.
        }
        if (null != resourceVersion) {
            resourceId = prefix + '/' + libraryName + '/' +
                    resourceName + '/' + resourceVersion;
        }
        else {
            resourceId = prefix + '/' + libraryName + '/' + resourceName;
        }
    } // end of if (null != libraryName)
    else {
        // libraryName == null
        var resourcePaths = resourceLoader.getResourcePaths(
                prefix + '/' + resourceName);
        if (null != resourcePaths && !resourcePaths.isEmpty()) {
            resourceVersion = // execute the comment
            // Look in the resourcePaths for versioned resources.
            // If one or more versioned resources are found, take
            // the one with the “highest� version number as the value
            // of resourceVersion. If no versioned libraries
            // are found, let resourceVersion remain null.
        }
        if (null != resourceVersion) {
            resourceId = prefix + '/' + resourceName + '/' +
                    resourceVersion;
        } else {
            resourceId = prefix + '/' + resourceName;
        }
    } // end of else, when libraryName == null
    return resourceId;
}

function getLocalePrefix() {
    var localePrefix;
    var appBundleName = facesContext.application.messageBundle;
    if (null != appBundleName) {
        var locale =
            // If there is a viewRoot on the current facesContext,
            // use its locale.
            // Otherwise, use the locale of the application's ViewHandler
        ResourceBundle appBundle = ResourceBundle.getBundle(
                appBundleName, locale);
        localePrefix = appBundle.getString(ResourceHandler. LOCALE_PREFIX);
    }
    // Any MissingResourceException instances that are encountered
    // in the above code must be swallowed by this method, and null
    // returned;
    return localePrefix;
}

[P1-end]

2.6.2. Rendering Resources

Resources such as images, stylesheets and scripts use the resource handling mechanism as outlined in See Packaging Resources. So, for example:

<h:graphicImage name=Planets.gif library=images/>
<h:graphicImage value=#{resource[images:Planets.gif]}/>

These entries render exactly the same markup. In addition to using the name and library attributes, stylesheet and script resources can be “relocated” to other parts of the view. For example, we could specify that a script resource be rendered within an HTML “head”, “body” or “form” element in the page.

2.6.2.1. Relocatable Resources

Relocatable resources are resources that can be told where to render themselves, and this rendered location may be different than the resource tag placement in the view. For example, a portion of the view may be described in the view declaration language as follows:

<f:view contentType="text/html">
  <h:head>
    <meta http-equiv="Content-Type"
        content="text/html;charset=iso-8859-1" />
    <title>Example View</title>
  </h:head>
  <h:body>
    <h:form>
      <h:outputScript name=ajax.js library=jakarta.faces
          target=head/>
    </h:form>
  </h:body>
</f:view>

The <h:outputScript> tag refers to the renderer, ScriptRenderer, that listens for PostAddToViewEvent event types:

@ListenerFor(facesEventClass=PostAddToViewEvent.class,
        sourceClass=UIOutput.class)
public class ScriptRenderer extends Renderer
        implements ComponentSystemEventListener {...

Refer to See Event and Listener Model. When the component for this resource is added to the view, the ScriptRenderer processEvent method adds the component to a facet (named by the target attribute) under the view root. using the UIViewRoot component resource methods as described in See Methods.

The <h:head> and <h:body> tags refer to the renderers HeadRenderer and BodyRenderer respectively. They are described in the Standard HTML Renderkit documentation referred to in See Standard HTML RenderKit Implementation. During the rendering phase, the encode methods for these renderers render the HTML “head” and “body” elements respectively. Then they render all component resources under the facet child (named by target) under the UIViewRoot using the UIViewRoot component resource methods as described in See Methods.

Existing component libraries (with existing head and body components), that want to use this resource loading feature must follow the rendering requirements described in See Standard HTML RenderKit Implementation.

2.6.2.2. Resource Rendering Using Annotations

Components and renderers may be declared as requiring a resource using the @ResourceDependency annotation. The implementation must scan for the presence of this annotation on the component that was added to the List of child components. Check for the presence of the annotation on the renderer for this component (if there is a renderer for the component). The annotation check must be done immediately after the component is added to the List. Refer to See Component Tree Manipulation for detailed information.

2.7. Resource Library Contracts

[P1-start_contract_packaging]A resource library contract is a resource library, as specified in the preceding section, except that instead of residing in the resources directory of the web-app root, or in the META-INF/resources JAR entry name in a JAR file, it resides in the contracts directory of the web-app root, or in the META-INF/contracts JAR entry name in a JAR file. When packaged in a JAR file, there is one additional packaging requirement: each resource library contract in the JAR must have a marker file. The name of the file is given by the value of the symbolic constant jakarta.faces.application.ResourceHandler.RESOURCE_CONTRACT_XML . This may be a zero length file, though future versions of the specification may use the file to declare the usage contract. [P1-end] The requirement to have a marker file enables implementations to optimize for faster deployment while still enabling automatic discovery of the available contracts.

Following is a listing of the entries in a JAR file containing two resource library contracts.

META-INF/contracts/
                  siteLayout/
                            jakarta.faces.contract.xml
                            topNav_template.xhtml
                            leftNav_foo.xhtml
                            styles.css
                            script.js
                            background.png
                  subSiteLayout/
                            jakarta.faces.contract.xml
                            sub_template.xhtml

All of the other packaging, encoding and decoding requirements are the same as for resource libraries.

See FaceletsAndWebApplications.adoc#a5526,See Resource Library Contracts Background>> for a non-normative overview of the feature, including a brief usage example.

3. User Interface Component Model

A Jakarta Faces user interface component is the basic building block for creating a Jakarta Faces user interface. A particular component represents a configurable and reusable element in the user interface, which may range in complexity from simple (such as a button or text field) to compound (such as a tree control or table). Components can optionally be associated with corresponding objects in the data model of an application, via value expressions.

Jakarta Faces also supports user interface components with several additional helper APIs:

  • Converters —Pluggable support class to convert the markup value of a component to and from the corresponding type in the model tier.

  • Events and Listeners —An event broadcast and listener registration model based on the design patterns of the JavaBeans Specification, version 1.0.1.

  • Validators —Pluggable support classes that can examine the local value of a component (as received in an incoming request) and ensure that it conforms to the business rules enforced by each Validator. Error messages for validation failures can be generated and sent back to the user during rendering.

The user interface for a particular page of a Jakarta Faces-based web application is created by assembling the user interface components for a particular request or response into a view. The view is a tree of classes that implement UIComponent. The components in the tree have parent-child relationships with other components, starting at the root element of the tree, which must be an instance of UIViewRoot. Components in the tree can be anonymous or they can be given a component identifier by the framework user. Components in the tree can be located based on component identifiers, which must be unique within the scope of the nearest ancestor to the component that is a naming container. For complex rendering scenarios, components can also be attached to other components as facets.

This chapter describes the basic architecture and APIs for user interface components and the supporting APIs.

3.1. UIComponent and UIComponentBase

The base abstract class for all user interface components is jakarta.faces.component.UIComponent. This class defines the state information and behavioral contracts for all components through a Java programming language API, which means that components are independent of a rendering technology such as Jakarta Server Pages. A standard set of components (described in Standard User Interface Components) that add specialized properties, attributes, and behavior, is also provided as a set of concrete subclasses.

Component writers, tool providers, application developers, and Jakarta Faces implementors can also create additional UIComponent implementations for use within a particular application. To assist such developers, a convenience subclass, jakarta.faces.component.UIComponentBase, is provided as part of Jakarta Faces. This class provides useful default implementations of nearly every UIComponent method, allowing the component writer to focus on the unique characteristics of a particular UIComponent implementation.

The following subsections define the key functional capabilities of Jakarta Faces user interface components.

3.1.1. Component Identifiers

public String getId();
public void setId(String componentId);

[N/T-start may-component-identifier] Every component may be named by a component identifier that must conform to the following rules:

  • They must start with a letter (as defined by the Character.isLetter() method).

  • Subsequent characters must be letters (as defined by the Character.isLetter() method), digits as defined by the Character.isDigit() method, dashes (‘-’), or underscores (‘_’).

[P1-end] To minimize the size of responses generated by Jakarta Server Faces, it is recommended that component identifiers be as short as possible.

If a component has been given an identifier, it must be unique in the namespace of the closest ancestor to that component that is a NamingContainer (if any).

3.1.2. Component Type

While not a property of UIComponent , the component-type is an important piece of data related to each UIComponent subclass that allows the Application instance to create new instances of UIComponent subclasses with that type. Please see Object Factories for more on component-type.

Component types starting with “jakarta.faces.” are reserved for use by the Jakarta Faces specification.

3.1.3. Component Family

public String getFamily();

Each standard user interface component class has a standard value for the component family, which is used to look up renderers associated with this component. Subclasses of a generic UIComponent class will generally inherit this property from its superclass, so that renderers who only expect the superclass will still be able to process specialized subclasses.

Component families starting with “jakarta.faces.” are reserved for use by the Jakarta Faces specification.

3.1.4. ValueExpression properties

Properties and attributes of standard concrete component classes may be value expression enabled. This means that, rather than specifying a literal value as the parameter to a property or attribute setter, the caller instead associates a ValueExpression (see ValueBinding) whose getValue() method must be called (by the property getter) to return the actual property value to be returned if no value has been set via the corresponding property setter. If a property or attribute value has been set, that value must be returned by the property getter (shadowing any associated value binding expression for this property).

Value binding expressions are managed with the following method calls:

public ValueExpression getValueExpression(String name);
public void setValueExpression(String name, ValueExpression expression);

where name is the name of the attribute or property for which to establish the value expression. [P1-start setValueExpression rules] The implementation of setValueExpression must detemine if the expression is a literal by calling ValueExpression.isLiteralText() on the expression argument. If the expression argument is literal text, then ValueExpression.getValue() must be called on the expression argument. The result must be used as the value argument, along with the name argument to this component’s getAttributes().put(name, value) method call. [P1-end] [P1-start which properties are value expression enabled] For the standard component classes defined by this specification, all attributes, and all properties other than id, parent, action, listener, actionListener, valueChangeListener, and validator are value expression enabled. The action, listener, actionListener, valueChangeListener, and validator attributes are method expression enabled.[P1-end]

In previous versions of this specification, this concept was called “value binding”. Methods and classes referring to this concept are deprecated, but remain implemented to preserve backwards compatibility.

public ValueBinding getValueBinding(String name);
public void setValueBinding(String name, ValueBinding binding);

Please consult the javadoc for these methods to learn how they are implemented in terms of the new “value expression” concept.

3.1.5. Component Bindings

A component binding is a special value expression that can be used to facilitate “wiring up” a component instance to a corresponding property of a JavaBean that is associated with the page, and wants to manipulate component instances programatically. It is established by calling setValueExpression() (see ValueExpression properties) with the special property name binding.

The specified ValueExpression must point to a read-write JavaBeans property of type UIComponent (or appropriate subclass). Such a component binding is used at two different times during the processing of a Faces Request:

  • [P3-start how a component binding is used from a Jakarta Server Pages page] When a component instance is first created (typically by virtue of being referenced by a UIComponentELTag in a Jakarta Server Pages page), the Jakarta Faces implementation will retrieve the ValueExpression for the name binding, and call getValue() on it. If this call returns a non-null UIComponent value (because the JavaBean programmatically instantiated and configured a component already), that instance will be added to the component tree that is being created. If the call returns null, a new component instance will be created, added to the component tree, and setValue() will be called on the ValueExpression (which will cause the property on the JavaBean to be set to the newly created component instance). [P3-end]

  • [P1-start how a component binding is used when restoring the tree]When a component tree is recreated during the Restore View phase of the request processing lifecycle, for each component that has a ValueExpression associated with the name “binding”, setValue() will be called on it, passing the recreated component instance. [P1-end]

Component bindings are often used in conjunction with JavaBeans that are dynamically instantiated via the Managed Bean Creation facility (see VariableResolver and the Default VariableResolver). If application developers place managed beans that are pointed at by component binding expressions in any scope other than request scope, the system cannot behave correctly. This is because placing it in a scope wider than request scope would require thread safety, since UIComponent instances depend on running inside of a single thread. There are also potentially negative impacts on memory management when placing a component binding in “session” or “view” scopes.

3.1.6. Client Identifiers

Client identifiers are used by Jakarta Faces implementations, as they decode and encode components, for any occasion when the component must have a client side name. Some examples of such an occasion are:

  • to name request parameters for a subsequent request from the Jakarta Faces-generated page.

  • to serve as anchors for client side scripting code.

  • to serve as anchors for client side accessibility labels.

public String getClientId(FacesContext context);
protected String getContainerClientId(FacesContext context);

The client identifier is derived from the component identifier (or the result of calling UIViewRoot.createUniqueId() if there is not one), and the client identifier of the closest parent component that is a NamingContainer according to the algorithm specified in the javadoc for UIComponent.getClientId(). The Renderer associated with this component, if any, will then be asked to convert this client identifier to a form appropriate for sending to the client. The value returned from this method must be the same throughout the lifetime of the component instance unless setId() is called, in which case it will be recalculated by the next call to getClientId().

3.1.7. Component Tree Manipulation

public UIComponent getParent();
public void setParent(UIComponent parent);

Components that have been added as children of another component can identify the parent by calling the getParent method. For the root node component of a component tree, or any component that is not part of a component tree, getParent will return null. In some special cases, such as transient components, it is possible that a component in the tree will return null from getParent(). The setParent() method should only be called by the List instance returned by calling the getChildren() method, or the Map instance returned by calling the getFacets() method, when child components or facets are being added, removed, or replaced.

public List<UIComponent> getChildren();

Return a mutable List that contains all of the child UIComponents for this component instance. [P1-start requirements of UIComponent.getChildren() ] The returned List implementation must support all of the required and optional methods of the List interface, as well as update the parent property of children that are added and removed, as described in the Javadocs for this method. [P1-end] Note that the add() methods have a special requirement to cause the PostAddToViewEvent method to be fired, as well as the processing of the ResourceDependency annotation. See the javadocs for getChildren() for details.

public int getChildCount();

A convenience method to return the number of child components for this component. [P2-start UIComponent.getChildCount requirements.] If there are no children, this method must return 0. The method must not cause the creation of a child component list, so it is preferred over calling getChildren().size() when there are no children. [P2-end]

3.1.8. Component Tree Navigation

public UIComponent findComponent(String expr);

Search for and return the UIComponent with an id that matches the specified search expression (if any), according to the algorithm described in the Javadocs for this method.

public Iterator<UIComponent> getFacetsAndChildren();

Return an immutable Iterator over all of the facets associated with this component (in an undetermined order), followed by all the child components associated with this component (in the order they would be returned by getChildren()).

public boolean invokeOnComponent(FacesContext context,
    String clientId, ContextCallback callback) throws FacesException;

Starting at this component in the view, search for the UIComponent whose getClientId() method returns a String that exactly matches the argument clientId using the algorithm specified in the Javadocs for this method. If such a UIComponent is found, call the invokeContextCallback() method on the argument callback passing the current FacesContext and the found UIComponent. Upon normal return from the callback, return true to the caller. If the callback throws an exception, it must be wrapped inside of a FacesException and re-thrown. If no such UIComponent is found, return false to the caller.

Special consideration should be given to the implementation of invokeOnComponent() for UIComponent classes that handle iteration, such as UIData. Iterating components manipulate their own internal state to handle iteration, and doing so alters the clientIds of components nested within the iterating component. Implementations of invokeOnComponent() must guarantee that any state present in the component or children is restored before returning. Please see the Javadocs for UIData.invokeOnComponent() for details.

The ContextCallback interface is specified as follows..

public interface ContextCallback {
  public void invokeContextCallback(
      FacesContext context, UIComponent target);
}

Please consult the Javadocs for more details on this interface.

public static UIComponent getCurrentComponent(FacesContext context);

Returns the UIComponent instance that is currently being processed.

public static UIComponent getCurrentCompositeComponent(
    FacesContext context);

Returns the closest ancestor component relative to getCurrentComponent that is a composite component, or null if no such component is exists.

public boolean visitTree(VisitContext context, VisitCallback callback);

Uses the visit API introduced in version 2 of the specification to perform a flexible and customizable visit of the tree from this instance and its children. Please see the package description for the package jakarta.faces.component.visit for the normative specification.

3.1.9. Facet Management

Jakarta Server Faces supports the traditional model of composing complex components out of simple components via parent-child relationships that organize the entire set of components into a tree, as described in Component Tree Manipulation. However, an additional useful facility is the ability to define particular subordinate components that have a specific role with respect to the owning component, which is typically independent of the parent-child relationship. An example might be a “data grid” control, where the children represent the columns to be rendered in the grid. It is useful to be able to identify a component that represents the column header and/or footer, separate from the usual child collection that represents the column data.

To meet this requirement, Jakarta Server Faces components offer support for facets, which represent a named collection of subordinate (but non-child) components that are related to the current component by virtue of a unique facet name that represents the role that particular component plays. Although facets are not part of the parent-child tree, they participate in request processing lifecycle methods, as described in Lifecycle Management Methods.

public Map<String, UIComponent> getFacets();

Return a mutable Map representing the facets of this UIComponent, keyed by the facet name.

public UIComponent getFacet(String name);

A convenience method to return a facet value, if it exists, or null otherwise. If the requested facet does not exist, no facets Map must not be created, so it is preferred over calling getFacets().get() when there are no Facets.

For easy use of components that use facets, component authors may include type-safe getter and setter methods that correspond to each named facet that is supported by that component class. For example, a component that supports a header facet of type UIHeader should have methods with signatures and functionality as follows:

public UIHeader getHeader() {
  return ((UIHeader) getFacet(header);
}

public void setHeader(UIHeader header) {
  getFacets().put(header, header);
}

3.1.10. Managing Component Behavior

UIComponentBase provides default implementations for the methods from the jakarta.faces.component.behavior.BehaviorHolder interface. UIComponentBase does not implement the jakarta.faces.component.behavior.BehaviorHolder interface, but it provides the default implementations to simplify subclass implemenations. Refer to Component Behavior Model for more information.

public void addBehavior(String eventName, Behavior behavior)

This method attaches a Behavior to the component for the specified eventName. The eventName must be one of the values in the Collection returned from getEventNames(). For example, it may be desired to have some behavior defined when a “click” event occurs. The behavior could be some client side behavior in the form of a script executing, or a server side listener executing.

public Collection<String> getEventNames()

Returns the logical event names that can be associated with behavior for the component.

public Map<String, List<Behavior>> getBehaviors()

Returns a Map defining the association of events and behaviors. They keys in the Map are event names.

public String getDefaultEventName()

Returns the default event name (if any) for the component.

3.1.11. Generic Attributes

public Map<String, Object> getAttributes();

The render-independent characteristics of components are generally represented as Jakarta Bean component properties with getter and setter methods (see Render-Independent Properties). In addition, components may also be associated with generic attributes that are defined outside the component implementation class. Typical uses of generic attributes include:

  • Specification of render-dependent characteristics, for use by specific Renderers.

  • General purpose association of application-specific objects with components.

The attributes for a component may be of any Java programming language object type, and are keyed by attribute name (a String). However, see State Saving Alternatives and Implications for implications of your application’s choice of state saving method on the classes used to implement attribute values.

Attribute names that begin with jakarta.faces are reserved for use by the Jakarta Faces specification. Names that begin with jakarta are reserved for definition through the Eclipse Foundation Process. Implementations are not allowed to define names that begin with jakarta.

[P1-start attribute property transparency rules] The Map returned by getAttributes() must also support attribute-property transparency, which operates as follows:

  • When the get() method is called, if the specified attribute name matches the name of a readable JavaBeans property on the component implementation class, the value returned will be acquired by calling the appropriate property getter method, and wrapping Java primitive values (such as int) in their corresponding wrapper classes (such as java.lang.Integer) if necessary. If the specified attribute name does not match the name of a readable JavaBeans property on the component implementation class, consult the internal data-structure to in which generic attributes are stored. If no entry exists in the internal data-structure, see if there is a ValueExpression for this attribute name by calling getValueExpression(), passing the attribute name as the key. If a ValueExpression exists, call getValue() on it, returning the result. If an ELException is thrown wrap it in a FacesException and re-throw it.

  • When the put() method is called, if the specified attribute name matches the name of a writable JavaBeans property on the component implementation class, the appropriate property setter method will be called. If the specified attribute name does not match the name of a writable JavaBeans property, simply put the value in the data-structure for generic attributes.

  • When the remove() method is called, if the specified attribute name matches the name of a JavaBeans property on the component, an IllegalArgumentException must be thrown.

  • When the containsKey() method is called, if the specified attribute name matches the name of a JavaBeans property, return false. Otherwise, return true if and only if the specified attribute name exists in the internal data-structure for the generic attributes.

The Map returned by getAttributes() must also conform to the entire contract for the Map interface. [P1-end]

3.1.11.1. Special Attributes
UIComponent Constants
public static final String CURRENT_COMPONENT =
    "jakarta.faces.component.CURRENT_COMPONENT";

This is used as a key in the FacesContext attributes Map to indicate the component that is currently being processed.

public static final String CURRENT_COMPOSITE_COMPONENT =
    "jakarta.faces.component.CURRENT_COMPOSITE_COMPONENT";

This is used as a key in the FacesContext attributes Map to indicate the composite component that is currently being processed.

public static final String BEANINFO_KEY =
    "jakarta.faces.component.BEANINFO_KEY";

This is a key in the component attributes Map whose value is a java.beans.BeanInfo describing the composite component.

public static final String FACETS_KEY =
    "jakarta.faces.component.FACETS_KEY";

This is a key in the composite component BeanDescriptor whose value is a Map<PropertyDescriptor> that contains meta-information for the declared facets for the composite component.

public static final String COMPOSITE_COMPONENT_TYPE_KEY =
    "jakarta.faces.component.COMPOSITE_COMPONENT_TYPE";

This is a key in the composite component BeanDescriptor whose value is a ValueExpression that evaluates to the component-type of the composite component root.

public static final String COMPOSITE_FACET_NAME =
    "jakarta.faces.component.COMPOSITE_FACET_NAME";

This is a key in the Map<PropertyDescriptor> that is returned by using the key FACETS_KEY. The value of this constant is also used as the key in the Map returned from getFacets(). In this case, the value of this key is the facet (the UIPanel) that is the parent of all the components in the composite implementation section of the composite component VDL file.

Refer to the jakarta.faces.component.UIComponent Javadocs for more detailed information.

3.1.12. Render-Independent Properties

The render-independent characteristics of a user interface component are represented as JavaBean component properties, following JavaBeans naming conventions. Specifically, the method names of the getter and/or setter methods are determined using standard JavaBeans component introspection rules, as defined by java.beans.Introspector. The render-independent properties supported by all UIComponents are described in the following table:

Name Access Type Description

id

RW

String

The component identifier, as described in Component Identifiers.

parent

RW

UIComponent

The parent component for which this component is a child or a facet.

rendered

RW

boolean

A flag that, if set to true, indicates that this component should be processed during all phases of the request processing lifecycle. The default value is “true”.

rendererType

RW

String

Identifier of the Renderer instance (from the set of Renderer instances supported by the RenderKit associated with the component tree we are processing. If this property is set, several operations during the request processing lifecycle (such as decode and the encodeXxx family of methods) will be delegated to a Renderer instance of this type. If this property is not set, the component must implement these methods directly.

rendersChildren

RO

boolean

A flag that, if set to true, indicates that this component manages the rendering of all of its children components (so the Jakarta Faces implementation should not attempt to render them). The default implementation in UIComponentBase delegates this setting to the associated Renderer, if any, and returns false otherwise.

transient

RW

boolean

A flag that, if set to true, indicates that this component must not be included in the state of the component tree. The default implementation in UIComponentBase returns false for this property.

The method names for the render-independent property getters and setters must conform to the design patterns in the JavaBeans specification. See State Saving Alternatives and Implications for implications of your application’s choice of state saving method on the classes used to implement property values.

3.1.13. Component Specialization Methods

The methods described in this section are called by the Jakarta Faces implementation during the various phases of the request processing lifecycle, and may be overridden in a concrete subclass to implement specialized behavior for this component.

public boolean broadcast(FacesEvent event)
    throws AbortProcessingException;

The broadcast() method is called during the common event processing (see Common Event Processing) at the end of several request processing lifecycle phases. For more information about the event and listener model, see Event and Listener Model. Note that it is not necessary to override this method to support additional event types.

public void decode(FacesContext context);

This method is called during the Apply Request Values phase of the request processing lifecycle, and has the responsibility of extracting a new local value for this component from an incoming request. The default implementation in UIComponentBase delegates to a corresponding Renderer, if the rendererType property is set, and does nothing otherwise.

Generally, component writers will choose to delegate decoding and encoding to a corresponding Renderer by setting the rendererType property (which means the default behavior described above is adequate).

public void encodeAll(FacesContext context) throws IOException
public void encodeBegin(FacesContext context) throws IOException;
public void encodeChildren(FacesContext context) throws IOException;
public void encodeEnd(FacesContext context) throws IOException;

These methods are called during the Render Response phase of the request processing lifecycle. encodeAll() will cause this component and all its children and facets that return true from isRendered() to be rendered, regardless of the value of the getRendersChildren() return value. encodeBegin(), encodeChildren(), and encodeEnd() have the responsibility of creating the response data for the beginning of this component, this component’s children (only called if the rendersChildren property of this component is true), and the ending of this component, respectively. Typically, this will involve generating markup for the output technology being supported, such as creating an HTML <input> element for a UIInput component. For clients that support it, the encode methods might also generate client-side scripting code (such as JavaScript), and/or stylesheets (such as CSS). The default implementations in UIComponentBase encodeBegin() and encodeEnd() delegate to a corresponding Renderer, if the rendererType property is true, and do nothing otherwise. [P1-start-comp-special]The default implementation in UIComponentBase encodeChildren() must iterate over its children and call encodeAll() for each child component. encodeBegin() must publish a PreRenderComponentEvent. [P1-end]

Generally, component writers will choose to delegate encoding to a corresponding Renderer, by setting the rendererType property (which means the default behavior described above is adequate).

public void queueEvent(FacesEvent event);

Enqueue the specified event for broadcast at the end of the current request processing lifecycle phase. Default behavior is to delegate this to the queueEvent() of the parent component, normally resulting in broadcast via the default behavior in the UIViewRoot lifecycle methods.

The component author can override any of the above methods to customize the behavior of their component.

3.1.14. Lifecycle Management Methods

The following methods are called by the various phases of the request processing lifecycle, and implement a recursive tree walk of the components in a component tree, calling the component specialization methods described above for each component. These methods are not generally overridden by component writers, but doing so may be useful for some advanced component implementations. See the javadocs for detailed information on these methods

In order to support the “component” implicit object (See Implicit Object ELResolver for Facelets and Programmatic Access), the following methods have been added to UIComponent

protected void pushComponentToEL(FacesContext context);
protected void popComponentFromEL(FacesContext context)

pushComponentToEL() and popComponentFromEL() must be called inside each of the lifecycle management methods in this section as specified in the javadoc for that method.

public void processRestoreState(FacesContext context, Object state);

Perform the component tree processing required by the Restore View phase of the request processing lifecycle for all facets of this component, all children of this component, and this component itself.

public void processDecodes(FacesContext context);

Perform the component tree processing required by the Apply Request Values phase of the request processing lifecycle for all facets of this component, all children of this component, and this component itself

public void processValidators(FacesContext context);

Perform the component tree processing required by the Process Validations phase of the request processing lifecycle for all facets of this component, all children of this component, and this component itself.

public void processUpdates(FacesContext context);

Perform the component tree processing required by the Update Model Values phase of the request processing lifecycle for all facets of this component, all children of this component, and this component itself.

public void processSaveState(FacesContext context);

Perform the component tree processing required by the state saving portion of the Render Response phase of the request processing lifecycle for all facets of this component, all children of this component, and this component itself.

3.1.15. Utility Methods

protected FacesContext getFacesContext();

Return the FacesContext instance for the current request.

protected Renderer getRenderer(FacesContext context);

Return the Renderer that is associated this UIComponent, if any, based on the values of the family and rendererType properties currently stored as instance data on the UIComponent.

protected void addFacesListener(FacesListener listener);
protected void removeFacesListener(FacesListener listener);

These methods are used to register and deregister an event listener. They should be called only by a public addXxxListener() method on the component implementation class, which provides typesafe listener registration.

public Map<String, String> getResourceBundleMap();

Return a Map of the ResourceBundle for this component. Please consult the Javadocs for more information.

3.2. Component Behavioral Interfaces

In addition to extending UIComponent, component classes may also implement one or more of the behavioral interfaces described below. Components that implement these interfaces must provide the corresponding method signatures and implement the described functionality.

3.2.1. ActionSource

The ActionSource interface defines a way for a component to indicate that wishes to be a source of ActionEvent events, including the ability invoke application actions (see Application Actions) via the default ActionListener facility (see ActionListener Property).

3.2.1.1. Properties

The following render-independent properties are added by the ActionSource interface:

Name Access Type Description

action

RW

MethodBinding

DEPRECATED A MethodBinding (see MethodBinding) that must (if non- null) point at an action method (see Application Actions). The specified method will be called during the Apply Request Values or Invoke Application phase of the request processing lifecycle, as described in Invoke Application. This method is replaced by the actionExpression property on ActionSource2. See the javadocs for the backwards compatibility implementation strategy.

actionListener

RW

MethodBinding

DEPRECATED A MethodBinding (see MethodBinding) that (if non- null) must point at a method accepting an ActionEvent, with a return type of void. Any ActionEvent that is sent by this ActionSource will be passed to this method along with the processAction() method of any registered ActionListeners, in either Apply Request Values or Invoke Application phase, depending upon the state of the immediate property. See the javadocs for the backwards compatibility implementation strategy.

immediate

RW

boolean

A flag indicating that the default ActionListener should execute immediately (that is, during the Apply Request Values phase of the request processing lifecycle, instead of waiting for Invoke Application phase). The default value of this property must be false.

3.2.1.2. Methods

ActionSource adds no new processing methods.

3.2.1.3. Events

A component implementing ActionSource is a source of ActionEvent events. There are three important moments in the lifetime of an ActionEvent :

  • when an the event is created

  • when the event is queued for later processing

  • when the listeners for the event are notified

ActionEvent creation occurs when the system detects that the component implementing ActionSource has been activated. For example, a button has been pressed. This happens when the decode() processing of the Apply Request Values phase of the request processing lifecycle detects that the corresponding user interface control was activated.

ActionEvent queueing occurs immediately after the event is created.

Event listeners that have registered an interest in ActionEvent s fired by this component (see below) are notified at the end of the Apply Request Values or Invoke Application phase, depending upon the immediate property of the originating UICommand .

ActionSource includes the following methods to register and deregister ActionListener instances interested in these events. See Event and Listener Model for more details on the event and listener model provided by Jakarta Faces.

public void addActionListener(ActionListener listener);
public void removeActionListener(ActionListener listener);

In addition to manually registered listeners, the Jakarta Faces implementation provides a default ActionListener that will process ActionEvent events during the Apply Request Values or Invoke Application phases of the request processing lifecycle. See RequestProcessingLifecycle.adoc#a454,Invoke Application>> for more information.

3.2.2. ActionSource2

The ActionSource2 interface extends ActionSource and provides a JavaBeans property analogous to the action property on ActionSource . This allows the ActionSource concept to leverage the Jakarta Expression Language API.

3.2.2.1. Properties

The following render-independent properties are added by the ActionSource interface:

Name Access Type Description

actionExpression

RW

jakarta.el.MethodExpression

A MethodExpression (see MethodBinding) that must (if non- null ) point at an action method (see Application Actions). The specified method will be called during the Apply Request Values or Invoke Application phase of the request processing lifecycle, as described in Invoke Application.

3.2.2.2. Methods

ActionSource2 adds no new processing methods.

3.2.2.3. Events

ActionSource2 adds no new events.

3.2.3. NamingContainer

NamingContainer is a marker interface. Components that implement NamingContainer have the property that, for all of their children that have non- null component identifiers, all of those identifiers are unique. This property is enforced by the renderView() method on ViewHandler . In Jakarta Server Pages based applications, it is also enforced by the UIComponentELTag . Since this is just a marker interface, there are no properties, methods, or events. Among the standard components, UIForm and UIData implement NamingContainer . See UIForm and Section Methods “UIData” for details of how the NamingContainer concept is used in these two cases.

NamingContainer defines a public static final character constant, SEPARATOR_CHAR , that is used to separate components of client identifiers, as well as the components of search expressions used by the findComponent() method see (Component Tree Navigation). The value of this constant must be a colon character (“:”).

Use of this separator character in client identifiers rendered by Renderer s can cause problems with CSS stylesheets that attach styles to a particular client identifier. For the Standard HTML RenderKit, this issue can be worked around by using the style attribute to specify CSS style values directly, or the styleClass attribute to select CSS styles by class rather than by identifier.

3.2.4. StateHolder

The StateHolder interface is implemented by UIComponent , Converter , FacesListener , and Validator classes that need to save their state between requests. UIComponent implements this interface to denote that components have state that must be saved and restored between requests.

3.2.4.1. Properties

The following render-independent properties are added by the StateHolder interface:

Name Access Type Description

transient

RW

boolean

A flag indicating whether this instance has decided to opt out of having its state information saved and restored. The default value for all standard component, converter, and validator classes that implement StateHolder must be false .

3.2.4.2. Methods

Any class implementing StateHolder must implement both the saveState() and restoreState() methods, since these two methods have a tightly coupled contract between themselves. In other words, if there is an inheritance hierarchy, it is not permissible to have the saveState() and restoreState() methods reside at different levels of the hierarchy.

public Object saveState(FacesContext context);
public void restoreState(FacesContext context,
    Object state) throws IOException;

Gets or restores the state of the instance as a Serializable Object .

If the class that implements this interface has references to Objects which also implement StateHolder (such as a UIComponent with a converter, event listeners, and/or validators) these methods must call the saveState() or restoreState() method on all those instances as well.

Any class implementing StateHolder must have a public no-args constructor.

If the state saving method is server, these methods may not be called.

If the class that implements this interface has references to Objects which do not implement StateHolder , these methods must ensure that the references are preserved. For example, consider class MySpecialComponent , which implements StateHolder , and keeps a reference to a helper class, MySpecialComponentHelper , which does not implement StateHolder . MySpecialComponent.saveState() must save enough information about MySpecialComponentHelper , so that when MySpecialComponent.restoreState() is called, the reference to MySpecialComponentHelper can be restored. The return from saveState() must be Serializable .

Since all of the standard user interface components listed in Standard User Interface Components” extend from UIComponent , they all implement the StateHolder interface. In addition, the standard Converter and Validator classes that require state to be saved and restored also implement StateHolder.

3.2.4.3. Events

StateHolder does not originate any standard events.

3.2.5. PartialStateHolder

PartialStateHolder extends StateHolder and adds a usage contract for components that wish to take part in the partial state saving mechanism introduced in version 2.0. Implementations of this interface should use the jakarta.faces.component.StateHelper instance returned from UIComponent.getStateHelper() to store stateful component information that otherwise would have been stored as instance variables on the class implementing PartialStateHolder .

3.2.5.1. Properties

PartialStateHolder adds no properties to the StateHolder contract

3.2.5.2. Methods

The following methods support the partial state saving feature:

void clearInitialState();
boolean initialStateMarked();
void markInitialState();

These methods allow the state saving feature to determine if the component is in its initial state or not, and to set the flag indicating this condition of existence. The Javadocs for these methods specify the conditions under which these methods are invoked.

3.2.5.3. Events

PartialStateHolder does not originate any standard events.

3.2.6. ValueHolder

ValueHolder is an interface that may be implemented by any concrete UIComponent that wishes to support a local value, as well as access data in the model tier via a value expression , and support conversion between String and the model tier data’s native data type.

3.2.6.1. Properties

The following render-independent properties are added by the ValueHolder interface:

Name Access Type Description

converter

RW

Converter

The Converter (if any) that is registered for this UIComponent.

value

RW

Object

First consult the local value property of this component. If non- null return it. If the local value property is null , see if we have a ValueExpression for the value property. If so, return the result of evaluating the property, otherwise return null .

localValue

RO

Object

allows any value set by calling setValue() to be returned, without potentially evaluating a ValueExpression the way that getValue() will do

Like nearly all component properties, the value property may have a value binding expression (see ValueExpression properties) associated with it. If present (and if there is no value set directly on this component), such an expression is utilized to retrieve a value dynamically from a model tier object during Render Response Phase of the request processing lifecycle. In addition, for input components, the value expression is used during Update Model Values phase (on the subsequent request) to push the possibly updated component value back to the model tier object.

The Converter property is used to allow the component to know how to convert the model type from the String format provided by the Servlet API to the proper type in the model tier.

The Converter property must be inspected for the presence of ResourceDependency and ResourceDependencies annotations as described in the Javadocs for the setConverter method.

3.2.6.2. Methods

ValueHolder adds no methods.

3.2.6.3. Events

ValueHolder does not originate any standard events.

3.2.7. EditableValueHolder

The EditableValueHolder interface (extends ValueHolder, see ValueHolder) describes additional features supported by editable components, including ValueChangeEvents and Validators.

3.2.7.1. Properties

The following render-independent properties are added by the EditableValueHolder interface:

Name Access Type Description

immediate

RW

boolean

Flag indicating that conversion and validation of this component’s value should occur during Apply Request Values phase instead of Process Validations phase.

localValueSet

RW

boolean

Flag indicating whether the value property has been set.

required

RW

boolean

Is the user required to provide a non-empty value for this component? Default value must be false.

submittedValue

RW

Object

The submitted, unconverted, value of this component. This property should only be set by the decode() method of this component, or its corresponding Renderer, or by the validate method of this component. This property should only be read by the validate() method of this component.

valid

RW

boolean

A flag indicating whether the local value of this component is valid (that is, no conversion error or validation error has occurred).

validator

RW

MethodBinding

DEPRECATED A MethodBinding that (if not null) must point at a method accepting a FacesContext and a UIInput, with a return type of void. This method will be called during Process Validations phase, after any validators that are externally registered. See the javadocs for the backwards compatibility strategy.

valueChangeListener

RW

MethodBinding

DEPRECATED A MethodBinding that (if not null) must point at a method that accepts a ValueChangeEvent, with a return type of void. The specified method will be called during the Process Validations phase of the request processing lifecycle, after any externally registered ValueChangeListeners. See the javadocs for the backwards compatibility strategy.

3.2.7.2. Methods

The following methods support the validation functionality performed during the Process Validations phase of the request processing lifecycle:

public void addValidator(Validator validator);
public void removeValidator(Validator validator);

The addValidator() and removeValidator() methods are used to register and deregister additional external Validator instances that will be used to perform correctness checks on the local value of this component.

If the validator property is not null, the method it points at must be called by the processValidations() method, after the validate() method of all registered Validator s is called.

The addValidator’s Validator argument must be inspected for the presense of the ResourceDependency and ResourceDependencies annotations as described in the Javadocs for the addValidator method.

3.2.7.3. Events

EditableValueHolder is a source of ValueChangeEvent, PreValidateEvent and PostValidate events. These are emitted during calls to validate(), which happens during the Process Validations phase of the request processing lifecycle. The PreValidateEvent is published immediately before the component gets validated. PostValidate is published after validation has occurred, regardless if the validation was successful or not. If the validation for the component did pass successfully, and the previous value of this component differs from the current value, the ValueChangeEvent is published. The following methods allow listeners to register and deregister for ValueChangeEvents. See Event and Listener Model for more details on the event and listener model provided by Jakarta Faces.

public void addValueChangeListener(ValueChangeListener listener);
public void removeValueChangeListener(ValueChangeListener listener);

In addition to the above listener registration methods, If the valueChangeListener property is not null, the method it points at must be called by the broadcast() method, after the processValueChange() method of all registered ValueChangeListener s is called.

3.2.8. SystemEventListenerHolder

Classes that implement this interface agree to maintain a list of SystemEventListener instances for each kind of SystemEvent they can generate. This interface enables arbitrary Objects to act as the source for SystemEvent instances.

3.2.8.1. Properties

This interface contains no JavaBeans properties

3.2.8.2. Methods

The following method gives the Jakarta Faces runtime access to the list of listeners stored by this instance.:

public List<FacesLifecycleListener> getListenersForEventClass(
    Class<? extends SystemEvent> facesEventClass);

During the processing for Application.publishEvent(), if the source argument to that method implements SystemEventListenerHolder, the getListenersForEventClass() method is invoked on it, and each listener in the list is given an opportunity to process the event, as specified in the javadocs for Application.publishEvent().

3.2.8.3. Events

While the class that implements SystemEventListenerHolder is indeed a source of events, it is a call to Application.publishEvent() that causes the event to actually be emitted. In the interest of maximum flexibility, this interface does not define how listeners are added, removed, or stored. See Event and Listener Model for more details on the event and listener model provided by Jakarta Faces.

3.2.9. ClientBehaviorHolder

[P1-start-addBehavior] Components must implement the ClientBehaviorHolder interface to add the ability for attaching ClientBehavior instances (see Component Behavior Model). Components that extend UIComponentBase only need to implement the getEventNames() method and specify "implements ClientBehaviorHolder". UIComponentBase provides base implementations for all other methods. [P1-end] The concrete HTML component classes that come with Jakarta Faces implement the ClientBehaviorHolder interface.

public void addClientBehavior(String eventName, ClientBehavior behavior);

Attach a ClientBehavior to a component implementing this ClientBehaviorHolder interface for the specified event. A default implementation of this method is provided in UIComponentBase to make it easier for subclass implementations to add behaviors.

public Collection<String> getEventNames();

Return a Collection of logical event names that are supported by the component implementing this ClientBehaviorHolder interface. [P1-start-getEventNames]The Collection must be non null and unmodifiable.[P1-end]

public Map<String, List<ClientBehavior>> getClientBehaviors();

Return a Map containing the event-client behavior association. Each event in the Map may contain one or more ClientBehavior instances that were added via the addClientBehavior() method.

[P1-start-getBehaviors]Each key value in this Map must be one of the event names in the Collection returned from getEventNames().[P1-end]

public String getDefaultEventName();

Return the default event name for this component behavior if the component defines a default event.

3.3. Conversion Model

This section describes the facilities provided by Jakarta Server Faces to support type conversion between server-side Java objects and their (typically String-based) representation in presentation markup.

3.3.1. Overview

A typical web application must constantly deal with two fundamentally different viewpoints of the underlying data being manipulated through the user interface:

  • The model view—Data is typically represented as Java programming language objects (often JavaBeans components), with data represented in some native Java programming language datatype. For example, date and time values might be represented in the model view as instances of java.util.Date.

  • The presentation view—Data is typically represented in some form that can be perceived or modified by the user of the application. For example, a date or type value might be represented as a text string, as three text strings (one each for month/date/year or one each for hour/minute/second), as a calendar control, associated with a spin control that lets you increment or decrement individual elements of the date or time with a single mouse click, or in a variety of other ways. Some presentation views may depend on the preferred language or locale of the user (such as the commonly used mm/dd/yy and dd/mm/yy date formats, or the variety of punctuation characters in monetary amount presentations for various currencies).

To transform data formats between these views, Jakarta Server Faces provides an ability to plug-in an optional Converter for each ValueHolder, which has the responsibility of converting the internal data representation between the two views. The application developer attaches a particular Converter to a particular ValueHolder by calling setConverter, passing an instance of the particular converter. A Converter implementation may be acquired from the Application instance (see Object Factories) for your application.

3.3.2. Converter

Jakarta Faces provides the jakarta.faces.convert.Converter interface to define the behavioral characteristics of a Converter. Instances of implementations of this interface are either identified by a converter identifier, or by a class for which the Converter class asserts that it can perform successful conversions, which can be registered with, and later retrieved from, an Application, as described in Object Factories.

Often, a Converter will be an object that requires no extra configuration information to perform its responsibilities. However, in some cases, it is useful to provide configuration parameters to the Converter (such as a java.text.DateFormat pattern for a Converter that supports java.util.Date model objects). Such configuration information will generally be provided via JavaBeans properties on the Converter instance.

Converter implementations should be programmed so that the conversions they perform are symmetric. In other words, if a model data object is converted to a String (via a call to the getAsString method), it should be possible to call getAsObject and pass it the converted String as the value parameter, and return a model data object that is semantically equal to the original one. In some cases, this is not possible. For example, a converter that uses the formatting facilities provided by the java.text.Format class might create two adjacent integer numbers with no separator in between, and in this case the Converter could not tell which digits belong to which number.

For UIInput and UIOutput components that wish to explicitly select a Converter to be used, a new Converter instance of the appropriate type must be created, optionally configured, and registered on the component by calling setConverter() 4. Otherwise, the Jakarta Faces implementation will automatically create new instances based on the data type being converted, if such Converter classes have been registered. In either case, Converter implementations need not be threadsafe, because they will be used only in the context of a single request processing thread.

The following two method signatures are defined by the Converter interface:

public Object getAsObject(FacesContext context,
    UIComponent component, String value) throws ConverterException;

This method is used to convert the presentation view of a component’s value (typically a String that was received as a request parameter) into the corresponding model view. It is called during the Apply Request Values phase of the request processing lifecycle.

public String getAsString(FacesContext context,
    UIComponent component, Object value) throws ConverterException;

This method is used to convert the model view of a component’s value (typically some native Java programming language class) into the presentation view (typically a String that will be rendered in some markup language. It is called during the Render Response phase of the request processing lifecycle.

[P1-start-converter-resource]If the class implementing Converter has a ResourceDependency annotation or a ResourceDependencies annotation, the action described in the Javadocs for the Converter interface must be followed when ValueHolder.setConverter is called.[P1-end]

3.3.3. Standard Converter Implementations

Jakarta Faces provides a set of standard Converter implementations. A Jakarta Faces implementation must register the DateTime and Number converters by name with the Application instance for this web application, as described in the table below. This ensures that the converters are available for subsequent calls to Application.createConverter(). Each concrete implementation class must define a static final String constant CONVERTER_ID whose value is the standard converter id under which this Converter is registered.

[P1-start standard converters] The following converter id values must be registered to create instances of the specified Converter implementation classes:

  • jakarta.faces.BigDecimal — An instance of jakarta.faces.convert.BigDecimalConverter (or a subclass of this class).

  • jakarta.faces.BigInteger — An instance of jakarta.faces.convert.BigIntegerConverter (or a subclass of this class).

  • jakarta.faces.Boolean — An instance of jakarta.faces.convert.BooleanConverter (or a subclass of this class).

  • jakarta.faces.Byte — An instance of jakarta.faces.convert.ByteConverter (or a subclass of this class).

  • jakarta.faces.Character — An instance of jakarta.faces.convert.CharacterConverter (or a subclass of this class).

  • jakarta.faces.DateTime — An instance of jakarta.faces.convert.DateTimeConverter (or a subclass of this class).

  • jakarta.faces.Double — An instance of jakarta.faces.convert.DoubleConverter (or a subclass of this class).

  • jakarta.faces.Float — An instance of jakarta.faces.convert.FloatConverter (or a subclass of this class).

  • jakarta.faces.Integer — An instance of jakarta.faces.convert.IntegerConverter (or a subclass of this class).

  • jakarta.faces.Long — An instance of jakarta.faces.convert.LongConverter (or a subclass of this class).

  • jakarta.faces.Number — An instance of jakarta.faces.convert.NumberConverter (or a subclass of this class).

  • jakarta.faces.Short — An instance of jakarta.faces.convert.ShortConverter (or a subclass of this class).

[P1-end] See the Javadocs for these classes for a detailed description of the conversion operations they perform, and the configuration properties that they support.

[P1-start by-Class converters] A Jakarta Faces implementation must register converters for all of the following classes using the by-type registration mechanism:

  • java.math.BigDecimal, and java.math.BigDecimal.TYPE — An instance of jakarta.faces.convert.BigDecimalConverter (or a subclass of this class).

  • java.math.BigInteger, and java.math.BigInteger.TYPE — An instance of jakarta.faces.convert.BigIntegerConverter (or a subclass of this class).

  • java.lang.Boolean, and java.lang.Boolean.TYPE — An instance of jakarta.faces.convert.BooleanConverter (or a subclass of this class).

  • java.lang.Byte, and java.lang.Byte.TYPE — An instance of jakarta.faces.convert.ByteConverter (or a subclass of this class).

  • java.lang.Character, and java.lang.Character.TYPE — An instance of jakarta.faces.convert.CharacterConverter (or a subclass of this class).

  • java.lang.Double, and java.lang.Double.TYPE — An instance of jakarta.faces.convert.DoubleConverter (or a subclass of this class).

  • java.lang.Float, and java.lang.Float.TYPE — An instance of jakarta.faces.convert.FloatConverter (or a subclass of this class).

  • java.lang.Integer, and java.lang.Integer.TYPE — An instance of jakarta.faces.convert.IntegerConverter (or a subclass of this class).

  • java.lang.Long, and java.lang.Long.TYPE — An instance of jakarta.faces.convert.LongConverter (or a subclass of this class).

  • java.lang.Short, and java.lang.Short.TYPE — An instance of jakarta.faces.convert.ShortConverter (or a subclass of this class).

  • java.lang.Enum, and java.lang.Enum.TYPE — An instance of jakarta.faces.convert.EnumConverter (or a subclass of this class).

[P1-end] See the Javadocs for these classes for a detailed description of the conversion operations they perform, and the configuration properties that they support.

[P1-start allowing string converters] A compliant implementation must allow the registration of a converter for class java.lang.String and java.lang.String.TYPE that will be used to convert values for these types. [P1-end]

3.4. Event and Listener Model

This section describes how Jakarta Server Faces provides support for generating and handling user interface events and system events.

3.4.1. Overview

Jakarta Faces implements a model for event notification and listener registration based on the design patterns in the JavaBeans Specification, version 1.0.1. This is similar to the approach taken in other user interface toolkits, such as the Swing Framework included in the JDK.

A UIComponent subclass may choose to emit events that signify significant state changes, and broadcast them to listeners that have registered an interest in receiving events of the type indicated by the event’s implementation class. At the end of several phases of the request processing lifecycle, the Jakarta Faces implementation will broadcast all of the events that have been queued to interested listeners. Jakarta Faces also defines system events. System events are events that are not specific to any particular application, but rather stem from specific points in time of running a Jakarta Faces application. The following UML class diagram illustrates the key players in the event model. Boxes shaded in gray indicate classes or interfaces defined outside of the jakarta.faces.event package.

image

3.4.2. Application Events

Application events are events that are specific to a particular application. Application events are the standard events that have been in Jakarta Faces from the beginning.

3.4.2.1. Event Classes

All events that are broadcast by Jakarta Faces user interface components must extend the jakarta.faces.event.FacesEvent abstract base class. The parameter list for the constructor(s) of this event class must include a UIComponent, which identifies the component from which the event will be broadcast to interested listeners. The source component can be retrieved from the event object itself by calling getComponent. Additional constructor parameters and/or properties on the event class can be used to relay additional information about the event.

In conformance to the naming patterns defined in the JavaBeans Specification, event classes typically have a class name that ends with Event. It is recommended that application event classes follow this naming pattern as well.

The component that is the source of a FacesEvent can be retrieved via this method:

public UIComponent getComponent();

FacesEvent has a phaseId property (of type PhaseId, see Phase Identifiers) used to identify the request processing lifecycle phase after which the event will be delivered to interested listeners.

public PhaseId getPhaseId();
public void setPhaseId(PhaseId phaseId);

If this property is set to PhaseId.ANY_PHASE (which is the default), the event will be delivered at the end of the phase in which it was enqueued.

To facilitate general management of event listeners in Jakarta Faces components, a FacesEvent implementation class must support the following methods:

public abstract boolean isAppropriateListener(FacesListener listener);
public abstract void processListener(FacesListener listener);

The isAppropriateListener() method returns true if the specified FacesListener is a relevant receiver of this type of event. Typically, this will be implemented as a simple “instanceof” check to ensure that the listener class implements the FacesListener subinterface that corresponds to this event class

The processListener() method must call the appropriate event processing method on the specified listener. Typically, this will be implemented by casting the listener to the corresponding FacesListener subinterface and calling the appropriate event processing method, passing this event instance as a parameter.

public void queue();

The above convenience method calls the queueEvent() method of the source UIComponent for this event, passing this event as a parameter.

Jakarta Faces includes two standard FacesEvent subclasses, which are emitted by the corresponding standard UIComponent subclasses described in the following chapter.

  • ActionEvent —Emitted by a UICommand component when the user activates the corresponding user interface control (such as a clicking a button or a hyperlink).

  • ValueChangeEvent —Emitted by a UIInput component (or appropriate subclass) when a new local value has been created, and has passed all validations.

3.4.2.2. Listener Classes

For each event type that may be emitted, a corresponding listener interface must be created, which extends the jakarta.faces.event.FacesListener interface. The method signature(s) defined by the listener interface must take a single parameter, an instance of the event class for which this listener is being created. A listener implementation class will implement one or more of these listener interfaces, along with the event handling method(s) specified by those interfaces. The event handling methods will be called during event broadcast, one per event.

In conformance to the naming patterns defined in the JavaBeans Specification, listener interfaces have a class name based on the class name of the event being listened to, but with the word Listener replacing the trailing Event of the event class name (thus, the listener for a FooEvent would be a FooListener). It is recommended that application event listener interfaces follow this naming pattern as well.

Corresponding to the two standard event classes described in the previous section, Jakarta Faces defines two standard event listener interfaces that may be implemented by application classes:

  • ActionListener —a listener that is interested in receiving ActionEvent events.

  • ValueChangeListener —a listener that is interested in receiving ValueChangeEvent events.

3.4.2.3. Phase Identifiers

As described in Common Event Processing, event handling occurs at the end of several phases of the request processing lifecycle. In addition, a particular event must indicate, through the value it returns from the getPhaseId() method, the phase in which it wishes to be delivered. This indication is done by returning an instance of jakarta.faces.event.PhaseId. The class defines a typesafe enumeration of all the legal values that may be returned by getPhaseId(). In addition, a special value (PhaseId.ANY_PHASE) may be returned to indicate that this event wants to be delivered at the end of the phase in which it was queued.

3.4.2.4. Listener Registration

A concrete UIComponent subclass that emits events of a particular type must include public methods to register and deregister a listener implementation. [P1-start listener methods must conform to javabeans naming] In order to be recognized by development tools, these listener methods must follow the naming patterns defined in the JavaBeans Specification. [P1-end] For example, for a component that emits FooEvent events, to be received by listeners that implement the FooListener interface, the method signatures (on the component class) must be:

public void addFooListener(FooListener listener);
public FooListener[] getFooListeners();
public void removeFooListener(FooListener listener);

The application (or other components) may register listener instances at any time, by calling the appropriate add method. The set of listeners associated with a component is part of the state information that Jakarta Faces saves and restores. Therefore, listener implementation classes must have a public zero-argument constructor, and may implement StateHolder (see StateHolder) if they have internal state information that needs to be saved and restored.

The UICommand and UIInput standard component classes include listener registration and deregistration methods for event listeners associated with the event types that they emit. The UIInput methods are also inherited by UIInput subclasses, including UISelectBoolean, UISelectMany, and UISelectOne.

3.4.2.5. Event Queueing

During the processing being performed by any phase of the request processing lifecycle, events may be created and queued by calling the queueEvent() method on the source UIComponent instance, or by calling the queue() method on the FacesEvent instance itself. As described in Common Event Processing, at the end of certain phases of the request processing lifecycle, any queued events will be broadcast to interested listeners in the order that the events were originally queued.

Deferring event broadcast until the end of a request processing lifecycle phase ensures that the entire component tree has been processed by that state, and that event listeners all see the same consistent state of the entire tree, no matter when the event was actually queued.

3.4.2.6. Event Broadcasting

As described in Common Event Processing, at the end of each request processing lifecycle phase that may cause events to be queued, the lifecycle management method of the UIViewRoot component at the root of the component tree will iterate over the queued events and call the broadcast() method on the source component instance to actually notify the registered listeners. See the Javadocs of the broadcast() method for detailed functional requirements.

During event broadcasting, a listener processing an event may:

  • Examine or modify the state of any component in the component tree.

  • Add or remove components from the component tree.

  • Add messages to be returned to the user, by calling addMessage on the FacesContext instance for the current request.

  • Queue one or more additional events, from the same source component or a different one, for processing during the current lifecycle phase.

  • Throw an AbortProcessingException, to tell the Jakarta Faces implementation that no further broadcast of this event should take place.

  • Call renderResponse() on the FacesContext instance for the current request. This tells the Jakarta Faces implementation that, when the current phase of the request processing lifecycle has been completed, control should be transferred to the Render Response phase.

  • Call responseComplete() on the FacesContext instance for the current request. This tells the Jakarta Faces implementation that, when the current phase of the request processing lifecycle has been completed, processing for this request should be terminated (because the actual response content has been generated by some other means).

3.4.3. System Events

System Events represent specific points in time for a Jakarta Faces application. PhaseEvents also represent specific points in time in a Jakarta Faces application, but the granularity they offer is not as precise as System Events. For more on PhaseEvents, please see PhaseEvent.

3.4.3.1. Event Classes

All system events extend from the base class SystemEvent. SystemEvent has a similar API to FacesEvent, but the source of the event is of type Object (instead of UIComponent ), SystemEvent has no PhaseId property and SystemEvent has no queue() method because SystemEvent s are never queued. SystemEvent shares isAppropriateListener() and processListener() with FacesEvent. For the specification of these methods see Event Classes.

System events that originate from or are associated with specific component instances should extend from ComponentSystemEvent, which extends SystemEvent and adds a getComponent() method, as specififed in Event Classes.

The specification defines the following SystemEvent subclasses, all in package jakarta.faces.event.

  • ExceptionQueuedEvent indicates a non-expected Exception has been thrown. Please see ExceptionHandler for the normative specification.

  • PostConstructApplicationEvent must be published immediately after application startup. Please see Application Startup Behavior for the normative specification.

  • PreDestroyApplicationEvent must be published as immediately before application shutdown. Please see Application Shutdown Behavior for the normative specification

  • PostKeepFlashEvent This event must be published by a call to Application.publishEvent() when a value is kept in the flash.

  • PostPutFlashEvent This event must be published by a call to Application.publishEvent() when a value is stored in the flash.

  • PreClearFlashEvent This event must be published by a call to Application.publishEvent() when a before the flash is cleared.

  • PreRemoveFlashEvent This event must be published by a call to Application.publishEvent() when a value is removed from the flash.

The specification defines the following ComponentSystemEvent classes, all in package jakarta.faces.event.

  • InitialStateEvent must be published with a direct call to UIComponent.processEvent(), during the apply() method of the class jakarta.faces.webapp.vdl.ComponentHandler. Please see the javadocs for the normative specification.

  • PostAddToViewEvent indicates that the source component has just been added to the view. Please see Component Tree Manipulation for a reference to the normative specification.

  • PostConstructViewMapEvent indicates that the Map that is the view scope has just been created. Please see, the UIViewRoot Events for a reference to the normative specification.

  • PostRenderViewEvent indicates that the UIViewRoot source component has just been rendered. Please see Render Response for the normative specification.

  • PostRestoreStateEvent indicates that an individual component instance has just had its state restored. Please see the UIViewRoot Events for a reference to the normative specification.

  • PostValidateEvent indicates that an individual component instance has just been validated. Please see the EditableValueHolder Events for the normative specification.

  • PreDestroyViewMapEvent indicates that the Map that is the view scope is about to be destroyed. Please see, the UIViewRoot Properties for the normative specification.

  • PreRenderComponentEvent indicates that the source component is about to be rendered. Please see Component Tree Manipulation for a reference to the normative specification.

  • PreRenderViewEvent indicates that the UIViewRoot source component is about to be rendered. Please see Render Response for the normative specification.

  • PreValidateEvent indicates that an individual component instance is about to be validated. Please see the EditableValueHolder Events for the normative specification.

3.4.3.2. Listener Classes

Unlike application events, the creation of new event types for system events does not require the creation of new listener interfaces. All SystemEvent types can be listened for by listeners that implement jakarta.faces.event.SystemEventListener. Please see the javadocs for that class for the complete specification.

As a developer convenience, the listener interface ComponentSystemEventListener has been defined for those cases when a SystemEventListener is being attached to a specific UIComponent instance. ComponentSystemEventListener lacks the isListenerForSource() method because it is implcictly defined by virture of the listener being added to a specific component instance.

3.4.3.3. Programmatic Listener Registration

System events may be listened for at the Application level, using Application.subscribeToEvent() or at the component level, by calling subscribeToEvent() on a specific component instance. The specification for Application.subscribeToEvent() may be found in System Event Methods.

The following methods are defined on UIComponent to support per-component system events.

public void subscribeToEvent(Class<? extends SystemEvent> eventClass,
    ComponentSystemEventListener componentListener);
public void unsubscribeFromEvent(Class<? extends SystemEvent> eventClass,
    ComponentSystemEventListener componentListener);

See the javadoc for UIComponent for the normative specification of these methods.

In addition to the above methods, the @ListenerFor and @ListenersFor annotations allow components, renderers, validators and converters to declare that they want to register for system events. Please see the javadocs for those annotations for the complete specification.

3.4.3.4. Declarative Listener Registration

Page authors can subscribe to events using the <f:event/> tag. This tag will allow the application developer to specify the method to be called when the specifed event fires for the component of which the tag is a child. The tag usage is as follows:

<h:inputText value="#{myBean.text}">
  <f:event type="preRenderComponent"
      listener="#{myBean.beforeTextRender}" />
</h:inputText>

The type attribute specifies the type of event, and can be any of the specification-defined events or one of any user-defined events, but must be a ComponentSystemEvent, using either the short-hand name for the event or the fully-qualified class name (e.g., com.foo.app.event.CustomEvent). If the event can not be found, a FacesException listing the offending event type will be thrown. Please see the VDLDocs for the <f:event /> tag for the normative specification of the declarative event feature.

The method signature for the MethodExpression pointed to by the listener attribute must match the signature of jakarta.faces.event.ComponentSystemEventListener.processEvent(), which is:

public void processEvent(jakarta.faces.event.ComponentSystemEvent event)
    throws AbortProcessingException
3.4.3.5. Listener Registration By Annotation

The ListenerFor and ListenersFor annotations can be applied to components and rendererers. Classes tagged with the ListenerFor annotation are installed as listeners. The ListenersFor annotation is a container annotation tp specify multiple ListenerFor annotations for a single class. Please refer to the Javadocs for the ListenerFor and ListenersFor classes for more details.

3.4.3.6. Listener Registration By Application Configuration Resources

A <system-event-listener> element, within the <application> element of an application configuration resource, declares an application scoped listener and causes a call to Application.subscribeToEvent().

3.4.3.7. Event Broadcasting

System events are broadcast immediately by calls to Application.publishEvent() Please see System Event Methods for the normative specification of publishEvent().

3.5. Validation Model

This section describes the facilities provided by Jakarta Server Faces for validating user input.

3.5.1. Overview

Jakarta Faces supports a mechanism for registering zero or more validators on each EditableValueHolder component in the component tree. A validator’s purpose is to perform checks on the local value of the component, during the Process Validations phase of the request processing lifecycle. In addition, a component may implement internal checking in a validate method that is part of the component class.

3.5.2. Validator Classes

A validator must implement the jakarta.faces.validator.Validator interface, which contains a validate() method signature.

public void validate(FacesContext context,
    UIComponent component, Object value);

General purpose validators may require configuration values in order to define the precise check to be performed. For example, a validator that enforces a maximum length might wish to support a configurable length limit. Such configuration values are typically implemented as JavaBeans component properties, and/or constructor arguments, on the Validator implementation class. In addition, a validator may elect to use generic attributes of the component being validated for configuration information.

Jakarta Faces includes implementations of several standard validators, as described in Standard Validator Implementations.

3.5.3. Validation Registration

The EditableValueHolder interface (implemented by UIInput) includes an addValidator method to register an additional validator for this component, and a removeValidator method to remove an existing registration. In pre-Jakarta Faces JSF 1.1 (under the JCP) there was the ability to set a MethodBinding that points to a method that adheres to the validate signature in the Validator interface, which will be called after the Validator instances added by calling addValidator() have been invoked. In pre-Jakarta Faces JSF 1.2 (under the JCP), this has been replaced by providing a new wrapper class that implements Validator, and accepts a MethodExpression instance that points to the same method that the MethodBinding pointed to in pre-Jakarta Faces JSF 1.1. Please see the javadocs for EditableValueHolder.setValidator().

The application (or other components) may register validator instances at any time, by calling the addValidator method. The set of validators associated with a component is part of the state information that Jakarta Faces saves and restores. Validators that wish to have configuration properties saved and restored must also implement StateHolder (see StateHolder).

In addition to validators which are registered explicitly on the component, either through the Java API or in the view markup, zero or more “default validators” can be declared in the application configuration resources, which will be registered on all UIInput instances in the component tree unless explicitly disabled. [P1-start-validator-reg]The default validators are appended after any locally defined validators once the EditableValueHolder is populated and added to the component tree. A default validator must not be added to a UIInput if a validator having the same id is already present.

The typical way of registering a default validator id is by declaring it in a configuration resource, as follows:

<faces-config>
  <application>
    <default-validators>
      <validator-id>jakarta.faces.Bean</validator-id>
    </default-validators>
  </application>
</faces-config>

A default validator may also be registered using the isDefault attribute on the @FacesValidator annotation on a Validator class, as specified in Requirements for scanning of classes for annotations.

The during application startup, the runtime must cause any default validators declared either in the application configuration resources, or via a @FacesValidator annotation with isDefault set to true to be added with a call to Application.addDefaultValidatorId(). This method is declared in Default Validator Ids.

Any configuration resource that declares a list of default validators overrides any list provided in a previously processed configuration resource. If an empty <default-validators/> element is found in a configuration resource, the list of default validators must be cleared.

In environments that include Bean Validation, the following additional actions must be taken at startup time. If the jakarta.faces.validator.DISABLE_DEFAULT_BEAN_VALIDATOR <context-param> exists and its value is true, the following step must be skipped:

  • The runtime must guarantee that the validator id jakarta.faces.Bean is included in the result from a call to Application.getDefaultValidatorInfo() (see Default Validator Ids), regardless of any configuration found in the application configuration resources or via the @FacesValidator annotation.[P1-end]

3.5.4. Validation Processing

During the Process Validations phase of the request processing lifecycle (as described in Process Validations), the Jakarta Faces implementation will ensure that the validate() method of each registered Validator , the method referenced by the validator property (if any), and the validate() method of the component itself, is called for each EditableValueHolder component in the component tree, regardless of the validity state of any of the components in the tree. The responsibilities of each validate() method include:

  • Perform the check for which this validator was registered.

  • If violation(s) of the correctness rules are found, create a FacesMessage instance describing the problem, and create a ValidatorException around it, and throw the ValidatorException. The EditableValueHolder on which this validation is being performed will catch this exception, set valid to false for that instance, and cause the message to be added to the FacesContext.

In addition, a validate() method may:

  • Examine or modify the state of any component in the component tree.

  • Add or remove components from the component tree.

  • Queue one or more events, from the same component or a different one, for processing during the current lifecycle phase.

The render-independent property required is a shorthand for the function of a “required” validator. If the value of this property is true, there is an entry in the request payload corresponding to this component, and the component has no value, the component is marked invalid and a message is added to the FacesContext instance. See Localized Application Messages for details on the message.

3.5.5. Standard Validator Implementations

Jakarta Server Faces defines a standard suite of Validator implementations that perform a variety of commonly required checks. In addition, component writers, application developers, and tool providers will often define additional Validator implementations that may be used to support component-type-specific or application-specific constraints. These implementations share the following common characteristics:

  • Standard Validators accept configuration information as either parameters to the constructor that creates a new instance of that Validator, or as JavaBeans component properties on the Validator implementation class.

  • To support internationalization, FacesMessage instances should be created. The message identifiers for such standard messages are also defined by manifest String constants in the implementation classes. It is the user’s responsibility to ensure the content of a FacesMessage instance is properly localized, and appropriate parameter substitution is performed, perhaps using java.text.MessageFormat.

  • See the javadocs for UIInput.validateValue() for further normative specification regarding validation.

  • Concrete Validator implementations must define a public static final String constant VALIDATOR_ID, whose value is the standard identifier under which the Jakarta Faces implementation must register this instance (see below).

Please see Localized Application Messages for the list of message identifiers.

[P1-start standard validators] The following standard Validator implementations (in the jakarta.faces.validator package) are provided:

  • DoubleRangeValidator —Checks the local value of a component, which must be of any numeric type, against specified maximum and/or minimum values. Standard identifier is “jakarta.faces.DoubleRange”.

  • LengthValidator —Checks the length (i.e. number of characters) of the local value of a component, which must be of type String, against maximum and/or minimum values. Standard identifier is “jakarta.faces.Length”.

  • LongRangeValidator —Checks the local value of a component, which must be of any numeric type convertible to long , against maximum and/or minimum values. Standard identifier is “jakarta.faces.LongRange”.

  • RegexValidator —Accepts a “pattern” attribute that is interpreted as a regular expression from the java.util.regex package. The local value of the component is checked fora match against this regular expression. Standard identifier is “jakarta.faces.RegularExpression”

  • BeanValidator - The implementation must ensure that this validator is only available when running in an environment in which JSR-303 Beans Validation is available. Please see the javadocs for BeanValidator.validate() for the specification. Standard identifier is “jakarta.faces.Bean”

  • RequiredValidator - Analogous to setting the required attribute to true on the EditableValueHolder. Enforces that the local value is not empty. Reuses the logic and error messages defined on UIInput. Standard identifier for this validator is "jakarta.faces.Required"

MethodExpressionValidator —Wraps a MethodExpression and interprets it as pointing to a method that performs validation. Any exception thrown when the expression is invoked is wrapped in a ValidatorException in similar fashion as the above validators. [P1-end]

3.5.6. Bean Validation Integration

If the implementation is running in a container environment that requires Jakarta Bean Validation, it must expose the bean validation as described in this specification.

As stated in the specification goals of Jakarta Bean Validation, validation often gets spread out across the application, from user interface components to persistent objects. Jakarta Bean Validation strives to avoid this duplication by defining a set of metadata that can be used to express validation constraints that are sharable by any layer of the application. Since its inception, Jakarta Faces has supported a “field level validation” approach. Rather than requiring the developer to define validators for each input component (i.e., EditableValueHolder), the BeanValidator can be automatically applied to all fields on a page so that the work of enforcing the constraints can be delegated to the Bean Validation provider.

3.5.6.1. Bean Validator Activation

[P1-BeanValidationIntegration]If Bean Validation is present in the runtime environment, the system must ensure that the standard validator with validator-id jakarta.faces.Bean is added with a call to Application.addDefaultValidatorId().[P1-end] See Standard Validator Implementations for the description of the standard BeanValidator, and <f:validateBean> for the Facelet tag that exposes this validator to the page author. This ensures Bean Validation will be called for every field in the application.

If Bean Validation is present, and the jakarta.faces.VALIDATE_EMPTY_FIELDS <context-param> is not explicitly set to false, Jakarta Faces will validate null and empty fields so that the @NotNull and @NotEmpty constraints from Bean Validation can be leveraged. The next section describes how the reference to the Bean Validation ValidatorFactory is obtained by that validator.

3.5.6.2. Obtaining a ValidatorFactory

The Bean Validation ValidatorFactory is the main entry point into Bean Validation and is responsible for creating Validator instances. [P1-start-validatoryfactory]A ValidatorFactory is retrieved using the following algorithm:

  • If the servlet context contains a ValidatorFactory instance under the attribute named jakarta.faces.validator.beanValidator.ValidatorFactory, this instance is used by Jakarta Faces to acquire Validator instances (specifically in the BeanValidator). This key should be defined in the constant named VALIDATOR_FACTORY_KEY on BeanValidator.

  • If the servlet context does not contain such an entry, Jakarta Faces looks for a Bean Validation provider in the classpath. If present, the standard Bean Validation bootstrap strategy is used. If not present, Bean Validation integration is disabled. If the BeanValidator is used an no ValidatorFactory can be retrieved, a FacesException is raised. The standard Bean Validation bootstrap procedure is shown here:

ValidatorFactory validatorFactory =
    Validation.buildDefaultValidatorFactory();

Once instantiated, the result can be stored in the servlet context attribute mentioned as a means of caching the result. If Jakarta Faces is running in a Jakarta EE environment, Jakarta Bean Validation will be available, as defined by the Jakarta EE specification, and thus activated in Jakarta Faces. The EE container will be responsible for making the ValidatorFactory available as an attribute in the ServletContext as mentioned above.[P1-end]

3.5.6.3. Class-Level Validation

Jakarta Faces conversion and validation as described in this chapter operates on the principle that all conversion and validation is performed before values are pushed into the model. This principle allows one to safely assume that if a value is pushed into the model, it is of the proper type and has been validated. This validation is done on a “field level” basis, as mentioned in Bean Validation Integration. This approach poses challenges for higher level validation that needs to take the value of several fields together into account to decide if they are valid or not. For example, consider the common case of a user account creation page with two fields for the password. The page can only be considered valid if both password fields are themselves individually valid based on the specified password constraints and also are both the same value. Jakarta Faces provides for this case by providing a facility for performing Class-Level Validation using Bean Validation. Please see the VDLDoc for the <f:validateWholeBean /> tag for the normative specification of this feature as well as a usage example showing the password validation scenario.

3.5.6.4. Localization of Bean Validation Messages

To ensure proper localization of the messages, Jakarta Faces should provide a custom BeanValidation MessageInterpolator resolving the Locale according to Jakarta Faces defaults and delegating to the default MessageInterpolator as defined in ValidationFactory.getMessageInterpolator(). A possible implementation is shown here:

public class FacesMessageInterpolator implements MessageInterpolator {
  private final MessageInterpolator delegate;

  public FacesMessageInterpolator(MessageInterpolator delegate) {
    this.delegate = delegate;
  }

  public String interpolate(String message,
      ConstraintDescriptor constraintDescriptor,Object value) {
    Locale locale = FacesContext.getCurrentInstance()
        .getViewRoot().getLocale();
    return this.delegate.interpolate(
        message, constraintDescriptor, value, locale);
  }

  public String interpolate(String message, ConstraintDescriptor
      constraintDescriptor, Object value, Locale locale) {
    return this.delegate.interpolate(
        message, constraintDescriptor, value, locale);
  }
}

Once a ValidatorFactory is obtained, as described in Obtaining a ValidatorFactory, Jakarta Faces receives a Validator instance by providing the custom message interpolator to the validator state.

//could be cached
MessageInterpolator facesMessageInterpolator = new FacesMessageInterpolator(
    validatorFactory.getMessageInterpolator() );

//...

Validator validator = validatorFactory
    .usingContext()
    .messageInterpolator(facesMessageInterpolator)
    .getValidator();

The local value is then passed to the Validator.validateValue() method to check for constraint violations. Since Bean Validation defines a strategy for localized message reporting, the BeanValidator does not need to concern itself with producing the validation message. Instead, the BeanValidator should accept the interpolated message returned from Bean Validation API, which is accessed via the method getInterpolatedMessage() on the ContraintFailure class, and use it as the replacement value for the first numbered placeholder for the key jakarta.faces.validator.BeanValidator.MESSAGE (i.e., {0}). To encourage use of the Bean Validation message facility, the default message format string for the BeanValidator message key must be a single placeholder, as shown here:

jakarta.faces.validator.BeanValidator.MESSAGE={0}

Putting the Bean Validation message resolution in full control of producing the displayed message is the recommended approach. However, to allow the developer to align the messages generated by the BeanValidator with existing Jakarta Faces validators, the developer may choose to override this message key in an application resource bundle and reference the component label, which replaces the second numbered placeholder (i.e., {1}).

jakarta.faces.validator.BeanValidator.MESSAGE={1}:{0}

This approach is useful if you are already using localized labels for your input components and are displaying the messages above the form, rather than adjacent to the input.

3.6. Composite User Interface Components

3.6.1. Non-normative Background

To aid implementors in providing a spec compliant runtime for composite components, this section provides a non-normative background to motivate the discussion of the composite component feature. The composite component feature enables developers to write real, reusable, Jakarta Faces UI components without any Java code or configuration XML.

3.6.1.1. What does it mean to be a Jakarta Faces User Interface component?

Jakarta Faces is a component based framework, and Jakarta Faces UI components are the main point of Jakarta Faces. But what is a Jakarta Faces UI component, really? Conceptually, a Jakarta Faces UI Component is a software artifact that represents a reusable, self contained piece of a user interface. A very narrow definition for “Jakarta Faces UI Component” is imposed at runtime. This definition can be summarized as

A Jakarta Faces UI Component is represented at runtime by an instance of a Java class that includes jakarta.faces.component.UIComponent as an ancestor in its inheritance hierarchy.

It is easy to write a class that adheres to this definition, but in practice, component authors need to do more than just this in order to get the most from Jakarta Faces and to conform to user’s expectations of what a Jakarta Faces UI Component is. For example, users expect a Jakarta Faces UI Component can do some or all of the following:

  • be exposed to the page-author via a markup tag with sensible attributes

  • emit events (such a ValueChangeEvent or ActionEvent)

  • allow attaching listeners

  • allow attaching a Converter and/or Validator(s)

  • render itself to the user-agent, with full support for styles, localization and accessibility

  • support delegated rendering to allow for client device independence

  • read values sent from the user-agent and correctly adapt them to the faces lifecycle

  • correctly handle saving and restoring its state across multiple requests from the user-agent

Another important dimension to consider regarding UI components is the context in which the developer interacts with the component. There are generally two such contexts.

  • In the context of a markup view, such as a Jakarta Server Pages or Facelet view. In this context the developer interacts with the UI component using a markup element, setting attributes on that element, and nesting child elements within that component markup element.

  • In the context of code, such as a listener, a managed-bean, or other programming language context. In this context, the developer is writing JavaCode that is either passed the UI component as an argument, or obtains a reference to the UI component in some other way.

3.6.1.2. How does one make a custom Jakarta Faces User Interface component?

To satisfy a user’s expectations for a Jakarta Faces UI component, the component author must adhere to one of the following best practices.

  • extend the custom component class from an existing subclass of UIComponent that most closely represents the meaning and behavior of the piece of the UI you are encapsulating in the component.

  • extend the custom component class directly from UIComponentBase and implement the appropriate “behavioral interface”(s) that most closely represents the meaning and behavior of the piece of the UI you are encapsulating in the component. See Component Behavioral Interfaces for more.

Note that the first best practice includes the second one “for free” since the stock UIComponent subclasses already implement the appropriate behavioral interfaces.

When following either best practice, the Jakarta Faces UI component developer must follow several steps to make the component available for use in markup pages or in code, including but not necessarily limited to

  • Make entries in a faces-config.xml file, linking the component class to its component-type , which enables the Application.createComponent() method to create instances of the component.

  • Make entries in a faces-config.xml file to declare a Renderer that provides client-device independence.

  • Provide a Jakarta Server Pages or Facelet tag handler that allows the page author to build UIs that include the component, and to customize each instance of the component with listeners, properties and model associations. This includes making the association between the Renderer and the UIComponent.

  • Provide a Renderer that provides client device independency for the component

  • Make entries in a faces-config.xml file that links the Renderer and its Java class.

These steps are complex, yet the components one creates by following them can be very flexible and powerful. By making some simplifying assumptions, it is possible to allow the creation of components that are just as powerful but require far less complexity to develop. This is the whole point of composite components: to enable developers to write real, reusable, Jakarta Faces UI components without any Java code or configuration XML.

3.6.1.3. How does one make a composite component?

The composite component feature builds on two features in Jakarta Faces: resources (Resource Handling) and Facelets (Facelets and its use in Web Applications”). Briefly, a composite component is any Facelet markup file that resides inside of a resource library. For example, if a Facelet markup file named loginPanel.xhtml resides inside of a resource library called ezcomp, then page authors can use this component by declaring the xml namespace xmlns:ez="http://java.sun.com/jsf/composite/ezcomp" and including the tag <ez:loginPanel /> in their pages. Naturally, it is possible for a composite component author to declare an alternate XML namespace for their composite components, but doing so is optional.

Any valid Facelet markup is valid for use inside of a composite component, including the templating features specified in Facelet Templating Tag Library. In addition, the tag library specified in Composite Component Tag Library must be used to declare the metadata for the composite component. Future versions of the Jakarta Faces specification may relax this requirement, but for now at least the <composite:interface> and <composite:implementation> sections are required when creating a composite component.

3.6.1.4. A simple composite component example

Create the page that uses the composite component, index.xhtml.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ez="http://java.sun.com/jsf/composite/ezcomp">
  <h:head>
    <title>A simple example of EZComp</title>
  </h:head>
  <h:body>
    <h:form>
      <ez:loginPanel id="loginPanel">
        <f:actionListener for="loginEvent"
            binding="#{bean.loginEventListener}" />
      </ez:loginPanel>
    </h:form>
  </h:body>
</html>

The only thing special about this page is the ez namespace declaration and the inclusion of the <ez:loginPanel /> tag on the page. The occurrence of the string “http://java.sun.com/jsf/composite/” in a Facelet XML namespace declaration means that whatever follows that last “/” is taken to be the name of a resource library. For any usage of this namespace in the page, such as <ez:loginPanel />, a Facelet markup file with the corresponding name is loaded and taken to be the composite component, in this case the file loginPanel.xhtml. The implementation requirements for this and other Facelet features related to composite components are specified in Requirements specific to composite components.

Create the composite component markup page. In this case, loginPanel.xhtml resides in the ./resources/ezcomp directory relative to the index.xhtml file.

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:composite="http://java.sun.com/jsf/composite">
  <head>
    <title>Not present in rendered output</title>
  </head>
  <body>
    <composite:interface>
      <composite:actionSource name="loginEvent" />
    </composite:interface>
    <composite:implementation>
      <p>Username: <h:inputText id="usernameInput" /></p>
      <p>Password: <h:inputSecret id="passwordInput" /></p>
      <p><h:commandButton id="loginEvent" value="login"/></p>
    </composite:implementation>
  </body>
</html>

The <composite:interface> section declares the public interface that users of this component need to understand. In this case, the component declares that it contains an implementation of ActionSource2 (see ActionSource2), and therefore anything one can do with an ActionSource2 in a Facelet markup page you one do with the composite component. (See Component Behavioral Interfaces for more on ActionSource2 and other behavioral interfaces). The <composite:implementation> section defines the implementation of this composite component.

3.6.1.5. Walk through of the run-time for the simple composite component example

This section gives a non-normative traversal of the composite component feature using the previous example as a guide. Please refer to the javadocs for the normative specification for each method mentioned below. Any text in italics is a term defined in Composite Component Terms.

  1. The user-agent requests the index.html from A simple composite component example. This page contains the ‘xmlns:ez="http://java.sun.com/jsf/composite/ezcomp"‘ declaration and an occurrence of the <ez:loginPanel> tag. Because this page contains a usage of a composite component, it is called a using page for discussion.

    The runtime notices the use of an xml namespace beginning with “http://java.sun.com/jsf/composite/”. Takes the substring of the namespace after the last “/”, exclusive, and looks for a resource library with the name “ezcomp” by calling ResourceHandler.libraryExists().

  2. The runtime encounters the <ez:loginPanel> component in the using page. This causes Application.createComponent(FacesContext, Resource) to be called. This method instantiates the top level component but does not populate it with children. Pay careful attention to the javadocs for this method. Depending on the circumstances, the top level component instance can come from a developer supplied Java Class, a Script, or an implementation specific java class. This method calls ViewDeclarationLanguage.getComponentMetadata(FacesContext, Resource), which obtains the composite component BeanInfo (and therefore also the composite component BeanDescriptor) that exposes the composite component metadata. The composite component metadata also includes any attached object targets exposed by the composite component author. One thing that Application.createComponent(FacesContext, Resource) does to the component before returning it is set the component’s renderer type to be jakarta.faces.Composite. This is important during rendering.

    Again, Application.createComponent(FacesContext, Resource) does not populate the top level component with children. Subsequent processing done as the runtime traverses the rest of the page takes care of that. One very important aspect of that subsequent processing is ensuring that all of the UIComponent children in the defining page are placed in a facet underneath the top level component. The name of that facet is given by the UIComponent.COMPOSITE_FACET_NAME constant.

  3. After the children of the composite component tag in the using page have been processed by the VDL implementation, the VDL implementation must call VDLUtils.retargetAttachedObjects(). This method examines the composite component metadata and retargets any attached objects from the using page to their approriate inner component targets.

  4. Because the renderer type of the composite component was set to jakarta.faces.Composite, the composite component renderer is invoked to render the composite component.

3.6.1.6. Composite Component Terms

The following terms are commonly used to describe the composite component feature.

Attached Object

Any artifact that can be attached to a UIComponent (composite or otherwise). Usually, this means a Converter, Validator, ActionListener, or ValueChangeListener.

Attached Object Target

Part of the composite component metadata that allows the composite component author to expose the semantics of an inner component to the using page author without exposing the rendering or implementation details of the inner component.

Composite Component

A tree of UIComponent instances, rooted at a top level component, that can be thought of and used as a single component in a view. The component hierarchy of this subtree is described in the composite component defining page.

Composite Component Author

The individual or role creating the composite component. This usually involves authoring the composite component defining page.

Composite Component BeanDescriptor

A constituent element of the composite component metadata. This version of the spec uses the JavaBeans API to expose the component metadata for the composite component. Future versions of the spec may use a different API to expose the component metadata.

Composite Component BeanInfo

The main element of the composite component metadata.

Composite Component Declaration

The section of markup within the composite component defining page that includes the <composite:interface> section and its children.

Composite Component Definition

The section of markup within the composite component defining page that includes the <composite:implementation> section and its children.

Composite Component Library

A resource library that contains a defining page for each composite component that the composite component author wishes to expose to the using page author.

Composite Component Metadata

Any data about the composite component. The normative specification for what must be in the composite component metadata is in the javadocs for ViewDeclarationLanguage.getComponentMetadata().

Composite Component Renderer

A new renderer in the HTML_BASIC render kit that knows how to render a composite component.

Composite Component Tag

The tag in the using page that references a composite component declared and defined in a defining page.

Defining page

The markup page, usually Facelets markup, that contains the composite component declaration and composite component definition.

Inner Component

Any UIComponent inside of the defining page or a page that is referenced from the defining page.

Top level component

The UIComponent instance in the tree that is the parent of all UIComponent instances within the defining page and any pages used by that defining page.

Using Page

The VDL page in which a composite component tag is used.

Using Page Author

The individual or role that creates pages that use the composite component.

3.6.2. Normative Requirements

This section contains the normative requirements for the composite component runtime, or pointers to other parts of the specification that articulate those requirements in the appropriate context.

Table 1. References to Composite Component Requirements in Context
Section Feature

Implicit Object ELResolver for Facelets and Programmatic Access

Ability for the composite component author to refer to the top level component from a Jakarta Expression Language expression, such as #{cc.children[3]}.

Composite Component Attributes ELResolver

Ability for the composite component author to refer to attributes declared on the composite component tag using EL expressions such as #{cc.attrs.usernameLabel}

Object Factories

Methods called by the VDL page to create a new instance of a top level component for eventual inclusion in the view

Requirements specific to composite components

Requirements of the Facelet implementation relating to Facelets.

Composite Component Tag Library

Tag handlers for the composite tag library

3.6.2.1. Composite Component Metadata

In the current version of the specification, only composite UIComponents must have component metadata. It is possible that future versions of the specification will broaden this requirement so that all UIComponents must have metadata.

This section describes the implementation of the composite component metadata that is returned from the method ViewDeclarationLanguage.getComponentMetadata(). This method is formally declared in ViewDeclarationLanguage.getComponentMetadata(), but for reference its signature is repeated here.

public BeanInfo getComponentMetadata(
    FacesContext context, Resource componentResource)

The specification requires that this method is called from Application.createComponent(FacesContext context, Resource componentResource). See the javadocs for that method for actions that must be taken based on the composite component metadata returned from getComponentMetadata().

The default implementation of this method must support authoring the component metadata using tags placed inside of a <composite:interface /> element found on a defining page. This element is specified in the Facelets taglibrary docs.

Composite component metadata currently consists of the following information:

  • The composite component BeanInfo, returned from this method.

  • The Resource from which the composite component was created.

  • The composite component BeanDescriptor.

    This BeanDescriptor must be returned when getBeanDescriptor() is called on the composite component BeanInfo.

    The composite component BeanDescriptor exposes the following information.

    • The “name” attributes of the <composite:interface/ > element is exposed using the corresponding method on the composite component BeanDescriptor. If ProjectStage is Development, The “displayName”, “shortDescription”, “expert”, “hidden”, and “preferred” attributes of the <composite:interface/ > element are exposed using the corresponding methods on the composite component BeanDescriptor. Any additional attributes on <composite:interface/ > are exposed as attributes accessible from the getValue() and attributeNames() methods on BeanDescriptor (inherited from FeatureDescriptor). The return type from getValue() must be a jakarta.el.ValueExpression for such attributes.

    • The list of exposed AttachedObjectTargets to which the page author can attach things such as listeners, converters, or validators.

      The VDL implementation must populate the composite component metadata with a List<AttachedObjectTarget> that includes all of the inner components exposed by the composite component author for use by the page author.

      This List must be exposed in the value set of the composite component BeanDescriptor under the key AttachedObjectTarget.ATTACHED_OBJECT_TARGETS_KEY.

      For example, if the defining page has

      <composite:interface>
        <composite:editableValueHolder name=username />
        <composite:actionSource name=loginEvent />
        <composite:actionSource name=allEvents
            targets=loginEvent cancelEvent />
      <composite:interface>

      The list of attached object targets would consist of instances of implementations of the following interfaces from the package jakarta.faces.webapp.vdl.

      1. EditableValueHolderAttachedObjectTarget

      2. ActionSource2AttachedObjectTarget

      3. ActionSource2AttachedObjectTarget

      4. BehaviorHolderAttachedObjectTarget

    • A ValueExpression that evaluates to the component type of the composite component. By default this is "jakarta.faces.NamingContainer" but the composite component page author can change this, or provide a Java or script-based UIComponent implementation that is required to implement NamingContainer.

      This ValueExpression must be exposed in the value set of the composite component BeanDescriptor under the key UIComponent.COMPOSITE_COMPONENT_TYPE_KEY.

    • A Map<String, PropertyDescriptor> representing the facets declared by the composite component author for use by the page author.

      This Map must be exposed in the value set of the composite component BeanDescriptor under the key UIComponent.FACETS_KEY.

    • Any attributes declared by the composite component author using <composite:attribute/ > elements must be exposed in the array of PropertyDescriptors returned from getPropertyDescriptors() on the composite component BeanInfo.

      For each such attribute, for any String or boolean valued JavaBeans properties on the interface PropertyDescriptor (and its superinterfaces) that are also given as attributes on a <composite:attribute/ > element, those properties must be exposed as properties on the PropertyDescriptor for that markup element. Any additional attributes on <composite:attribute/ > are exposed as attributes accessible from the getValue() and attributeNames() methods on PropertyDescriptor. The return type from getValue() must be a ValueExpression with the exception of the getValue(“type”). The return type from getValue(“type”) must be Class. If the value specified for the type attribute of <cc:attribute/> cannot be converted to an actual Class, a TagAttributeException must be thrown, including the Tag and TagAttribute instances in the constructor.

      The composite component BeanDescriptor must return a Collection<String> when its getValue() method is called with an argument equal to the value of the symbolic constant UIComponent.ATTRS_WITH_DECLARED_DEFAULT_VALUES. The Collection<String> must contain the names of any <composite:attribute> elements for which the default attribute was specified, or null if none of the attributes have been given a default value.

3.7. Component Behavior Model

This section describes the facilities for adding Behavior attached objects to Jakarta Server Faces components.

3.7.1. Overview

Jakarta Faces supports a mechanism for enhancing components with additional behaviors that are not explicitly defined by the component author.

At the root of the behavior model is he Behavior interface. This interface serves as a supertype for additional behavior contracts. The ClientBehavior interface extends the Behavior interface by providing a contract for defining reusable scripts that can be attached to any component that implements the ClientBehaviorHolder interface. The ClientBehaviorHolder interface defines the set of attach points, or "events", to which a ClientBehavior may be attached. For example, an "AlertBehavior" implementation might display a JavaScript alert when attached to a component and activated by the end user.

While client behaviors typically add client-side capabilities, they are not limited to client. Client behaviors can also participate in the Jakarta Faces request processing lifecycle. Jakarta Faces’s AjaxBehavior is a good example of such a cross-tier behavior. The AjaxBehavior both triggers an Ajax request from the client and also delivers AjaxBehaviorEvents to listeners on the server.

The standard HTML components provided by Jakarta Faces are all client behavior-ready. That is, all of the standard HTML components implement the ClientBehaviorHolder interface and allow client behaviors to be attached to well defined events. .

3.7.2. Behavior Interface

The Behavior interface is the root of the component behavior model. It defines a single method to enable generic behavior event delivery.

public void broadcast(BehaviorEvent event) throws AbortProcessingException

This method is called by UIComponent implementations to re-broadcast behavior events that were queued by by calling UIComponent.queueEvent.

3.7.3. BehaviorBase

The BehaviorBase abstract class implements the broadcast method from the Behavior interface. BehaviorBase also implements the PartialStateHolder interface (see PartialStateHolder). It also provides behavior event listener registration methods.

public void broadcast(BehaviorEvent event) throws AbortProcessingException

This method delivers the BehaviorEvent to listeners that were registered via addBehaviorListener.

The following methods are provided for add and removing BehaviorListeners.

protected void addBehaviorListener(BehaviorListener listener)
protected void removeBehaviorListener(BehaviorListener listener);

3.7.4. The Client Behavior Contract

The ClientBehavior interface extends the Behavior interface and lays the foundation on which behavior authors can define custom script producing behaviors. The logic for producing these scripts is defined in the getScript() method.

public String getScript(BehaviorContext behaviorContext)

This method returns a String that is an executable script that can be attached to a client side event handler. The BehaviorContext argument contains information that may be useful for getScript implementations.

In addition to client side functionality, client behaviors can also post back to the server and participate in the request processing lifecycle.

public void decode(FacesContext context,UIComponent component)

This method can perform request decoding and queue server side events.

public Set<ClientBehaviorHint> getHints()

This method provides information about the client behavior implementation that may be useful to components and renderers that interact with the client behavior.

Refer to the javadocs for these methods for more details.

3.7.5. ClientBehaviorHolder

Components that support client behaviors must implement the ClientBehaviorHolder interface. Refer to ClientBehaviorHolder for more details.

3.7.6. ClientBehaviorRenderer

Client behaviors may implement script generation and decoding in a client behavior class or delegate to a ClientBehaviorRenderer. Refer to ClientBehaviorRenderer for more specifics.

3.7.7. ClientBehaviorContext

The specification provides a ClientBehaviorContext that contains information that may be used at script rendering time. Specifically it includes:

  • FacesContext

  • UIComponent that the current behavior is attached to

  • The name of the event that the behavior is associated with

  • The identifier of the source - this may correspond to the identifier of the source of the behavior

  • A collection of parameters that submitting behaviors should include when posting back to the server

The ClientBehaviorContext is created with the use of this static method:

public static ClientBehaviorContext createClientBehaviorContext(
    FacesContext context,UIComponent component,
    String eventName, String sourceId,
    Collection<ClientBehaviorContext.Parameter> parameters)

This method must throw a NullPointerException if context, component or eventName is null.

3.7.8. ClientBehaviorHint

The ClientBehaviorHint enum is used to convey information about the client behavior implementation. Currently, only one hint is provided.

SUBMITTING

This hint indicates that a client behavior implementation posts back to the server.

3.7.9. ClientBehaviorBase

ClientBehaviorBase is an extension of BehaviorBase that implements the ClientBehavior interface. It It is a convenience class that contains default implementations for the methods in ClientBehavior plus additional methods:

public String getScript(BehaviorContext behaviorContext)

The default implementation calls getRenderer to retrieve the ClientBehaviorRenderer. If a ClientBehaviorRenderer is found, it is used to obtain the script. If no ClientBehaviorRenderer is found, this method returns null.

public void decode(FacesContext context,UIComponent component)

The default implementation calls getRenderer to retrieve the ClientBehaviorRenderer. If a ClientBehaviorRenderer is found, it is used to perform decoding. If no ClientBehaviorRenderer is found, no decoding is performed.

public Set<ClientBehaviorHint> getHints()

The default implementation returns an empty set

public String getRendererType();

This method identifies the ClientBehaviorRenderer type. By default, no ClientBehaviorRenderer type is provided. Subclasses should either override this method to return a valid type or override the getScript and decode methods if a ClientBehaviorRenderer is not available.

protected ClientBehaviorRenderer getRenderer(FacesContext context);

This method returns the ClientBehaviorRenderer instance that is associated with this ClientBehavior. It uses the renderer type returned from get RendererType() to look up the renderer on the RenderKit using RenderKit.getClientBehaviorRenderer.

3.7.10. Behavior Event / Listener Model

The behavior event / listener model is an extension of the Jakarta Faces event / listener model as described in Event and Listener Model. BehaviorHolder components are responsible for broadcasting BehaviorEvents to behaviors.

3.7.10.1. Event Classes

Behaviors can broadcast events in the same way that UIComponents can broadcast events. At the root of the behavior event hierarchy is BehaviorEvent that extends jakarta.faces.event.FacesEvent. All events that are broadcast by Jakarta Faces behaviors must extend the jakarta.faces.event.BehaviorEvent abstract base class. The parameter list for the constructor(s) of this event class must include a UIComponent, which identifies the component from which the event will be broadcast to interested listeners, and a Behavior which identifies the behavior associated with the component. The source component can be retrieved from the event object itself by calling getComponent and the behavior can be retrieved by calling getBehavior. Additional constructor parameters and/or properties on the event class can be used to relay additional information about the event.

In conformance to the naming patterns defined in the JavaBeans Specification, event classes typically have a class name that ends with Event. The following method is available to determine the Behavior for the event (in addition to the other methods inherited from jakarta.faces.event.FacesEvent):

public Behavior getBehavior()
3.7.10.2. Listener Classes

For each event type that may be emitted, a corresponding listener interface must be created, which extends the jakarta.faces.event.BehaviorListener interface. BehaviorListener extends from jakarta.faces.event.FacesListener. The method signature(s) defined by the listener interface must take a single parameter, an instance of the event class for which this listener is being created. A listener implementation class will implement one or more of these listener interfaces, along with the event handling method(s) specified by those interfaces. The event handling methods will be called during event broadcast, one per event.

In conformance to the naming patterns defined in the JavaBeans Specification, listener interfaces have a class name based on the class name of the event being listened to, but with the word Listener replacing the trailing Event of the event class name (thus, the listener for a FooEvent would be a FooListener). It is recommended that application event listener interfaces follow this naming pattern as well.

3.7.10.3. Listener Registration

BehaviorListener registration follows the same conventions as outlined in Listener Registration.

3.7.11. Ajax Behavior

3.7.11.1. AjaxBehavior

The specification defines a single concrete ClientBehavior implementation: jakarta.faces.component.behavior.AjaxBehavior. This class extends jakarta.faces.component.behavior.ClientBehaviorBase. The presence of this behavior on a component causes the rendering of JavaScript that will produce an Ajax request to the server using the JavaScript API outlined in Section “JavaScript API”. This behavior may also broadcast jakarta.faces.event.AjaxBehaviorEvents to registered jakarta.faces.event.AjaxBehaviorListener implementations. Refer to the javadocs for more details about AjaxBehavior. [P1-start-ajaxbehavior]This behavior must define the behavior id “jakarta.faces.behavior.Ajax”. The renderer type must also be “jakarta.faces.behavior.Ajax”.[P1-end]

3.7.11.2. Ajax Behavior Event / Listener Model

Corresponding to the standard behavior event classes described in the previous section the specification supports an event listener model for broadcasting and handling AjaxBehavior events.

jakarta.faces.event.AjaxBehaviorEvent

This event type extends from jakarta.faces.event.BehaviorEvent and it is broadcast from an AjaxBehavior. This class follows the standard Jakarta Faces event / listener model, incorporating the usual methods as outlined in Event and Listener Model. This class is responsible for invoking the method implementation of jakarta.faces.event.AjaxBehaviorListener.processAjaxBehavior. Refer to the javadocs for more complete details about this class.

jakarta.faces.event.AjaxBehaviorListener

This listener type extends from jakarta.faces.event.BehaviorListener and it is invoked in response to AjaxBehaviorEvents.

public void processAjaxBehavior(AjaxBehaviorEvent event)

AjaxBehaviorListener implementations implement this method to provide server side functionality in response to AjaxBehavior Events. See the javadocs for more details about this class.

3.7.12. Adding Behavior To Components

Using the ClientBehaviorHolder interface (See ClientBehaviorHolder) ClientBehavior instances can be added to components. For ClientBehavior implementations that extend UIComponentBase, the minimal requirement is to override getEventNames() to return a non-empty collection of the event names exposed by the ClientBehaviorHolder. A optional default event name may be specified as well. For example:

Here’s an example code snippet from one of the Html components:

public class HtmlCommandButton extends
    jakarta.faces.component.UICommand implements ClientBehaviorHolder {
...
  private static final Collection<String> EVENT_NAMES =
      Collections.unmodifiableCollection(
          Arrays.asList("blur","change","click","action",...) );

  public Collection<String> getEventNames() {
    return EVENT_NAMES;
  }

  public String getDefaultEventName() {
    return "action";
  }
...

Users of the component will be able to attach ClientBehavior instances to any of the event names specified by the getEventNames() implementation by calling ClientBehaviorHolder.addBehavior(eventName, clientBehavior).

3.7.13. Behavior Registration

Jakarta Faces provides methods for registering Behavior implementations and these methods are similar to the methods used to register converters and validators. Refer to Object Factories for the specifics about these methods.

3.7.13.1. XML Registration

Jakarta Faces provides the usual faces-config.xml registration of custom component behavior implementations.

<behavior>
  <behavior-id>custom.behavior.Greet</behavior-id>
  <behavior-class>greet.GreetBehavior</behavior-class>
</behavior>
3.7.13.2. Registration By Annotation

Jakarta Faces provides the @FacesBehavior annotation for registering custom behavior implementations.

@FacesBehavior(value="custom.behavior.Greet")
public class GreetBehavior extends BehaviorBase implements Serializable {
...
}

4. Standard User Interface Components

In addition to the abstract base class UIComponent and the abstract base class UIComponentBase, described in the previous chapter, Jakarta Faces provides a number of concrete user interface component implementation classes that cover the most common requirements. In addition, component writers will typically create new components by subclassing one of the standard component classes (or the UIComponentBase class). It is anticipated that the number of standard component classes will grow in future versions of the Jakarta Server Faces specification.

Each of these classes defines the render-independent characteristics of the corresponding component as JavaBeans component properties. Some of these properties may be value expressions that indirectly point to values related to the current request, or to the properties of model data objects that are accessible through request-scope, session-scope, or application-scope attributes. In addition, the rendererType property of each concrete implementation class is set to a defined value, indicating that decoding and encoding for this component will (by default) be delegated to the corresponding Renderer.

4.1. Standard User Interface Components

This section documents the features and functionality of the standard UIComponent classes and implementations that are included in Jakarta Server Faces.

[P1-start-componentConstant]The implementation for each standard UIComponent class must specify two public static final String constant values:

  • COMPONENT_TYPE — The standard component type identifier under which the corresponding component class is registered with the Application object for this application. This value may be used as a parameter to the createComponent() method.

  • COMPONENT_FAMILY — The standard component family identifier used to select an appropriate Renderer for this component.[P1-end]

For all render-independent properties in the following sections (except for id, scope, and var) the value may either be a literal, or it may come from a value expression. Please see Value Expressions for more information.

The following UML class diagram shows the classes and interfaces in the package jakarta.faces.component.

The jakarta.faces.component package

image

4.1.1. UIColumn

UIColumn (extends UIComponentBase) is a component that represents a single column of data with a parent UIData component. The child components of a UIColumn will be processed once for each row in the data managed by the parent UIData.

4.1.1.1. Component Type

The standard component type for UIColumn components is “jakarta.faces.Column”.

4.1.1.2. Properties

UIColumn adds the following render-independent properties:

Name Access Type Description

footer

RW

UIComponent

Convenience methods to get and set the “footer” facet for this component.

header

RW

UIComponent

Convenience methods to get and set the “header” facet for this component.

[P1-start-uicolumn]UIColumn specializes the behavior of render-independent properties inherited from the parent class as follows:

  • The default value of the family property must be set to “jakarta.faces.Column”.

  • The default value of the rendererType property must be set to null.[P1-end]

4.1.1.3. Methods

UIColumn adds no new processing methods.

4.1.1.4. Events

UIColumn adds no new event handling methods.

4.1.2. UICommand

UICommand (extends UIComponentBase; implements ActionSource) is a control which, when activated by the user, triggers an application-specific “command” or “action.” Such a component is typically rendered as a push button, a menu item, or a hyperlink.

4.1.2.1. Component Type

The standard component type for UICommand components is “jakarta.faces.Command”.

4.1.2.2. Properties

UICommand adds the following render-independent properties.

Name Access Type Description

value

RW

Object

The value of this component, normally used as a label.

See ActionSource for information about properties introduced by the implemented classes.

[P1-start-uicommand]UICommand components specialize the behavior of render-independent properties inherited from the parent class as follows:

  • The default value of the family property must be set to “jakarta.faces.Command”.

  • The default value of the rendererType property must be set to “jakarta.faces.Button”.[P1-end]

4.1.2.3. Methods

UICommand adds no new processing methods. See ActionSource for information about methods introduced by the implemented classes.

4.1.2.4. Events

UICommand adds no new event processing methods. See ActionSource for information about event handling introduced by the implemented classes.

4.1.3. UIData

UIData (extends UIComponentBase; implements NamingContainer) is a component that represents a data binding to a collection of data objects represented by a DataModel instance (see DataModel). Only children of type UIColumn should be processed by renderers associated with this component.

4.1.3.1. Component Type

The standard component type for UIData components is “jakarta.faces.Data”

4.1.3.2. Properties

UIData adds the following render-independent properties.

Name Access Type Description

dataModel

protected RW

DataModel

The internal value representation of the UIData instance. Subclasses might write to this property if they want to restore the internal model during the Restore View Phase or if they want to explicitly refresh the model for the Render Response phase.

first

RW

int

Zero-relative row number of the first row in the underlying data model to be displayed, or zero to start at the beginning of the data model.

footer

RW

UIComponent

Convenience methods to get and set the “footer” facet for this component.

header

RW

UIComponent

Convenience methods to get and set the “header” facet for this component.

rowCount

RO

int

The number of rows in the underlying DataModel, which can be -1 if the number of rows is unknown.

rowAvailable

RO

boolean

Return true if there is row data available for the currently specified rowIndex ; else return false .

rowData

RO

Object

The data object representing the data for the currently selected rowIndex value.

rowIndex

RW

int

Zero-relative index of the row currently being accessed in the underlying DataModel, or -1 for no current row. See below for further information.

rows

RW

int

The number of rows (starting with the one identified by the first property) to be displayed, or zero to display the entire set of available rows.

value

RW

Object

The DataModel instance representing the data to which this component is bound, or a collection of data for which a DataModel instance is synthesized. See below for more information.

var

RW

String

The request-scope attribute (if any) under which the data object for the current row will be exposed when iterating.

See NamingContainer for information about properties introduced by the implemented classes.

[P1-start-uidata]UIData specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Data”.

  • The default value of the rendererType property must be set to “jakarta.faces.Table”.[P1-end]

The current value identified by the value property is normally of type DataModel. [P1-start-uidataModel]However, a DataModel wrapper instance must automatically be provided by the Jakarta Faces implementation if the current value is of one of the following types:

  • java.util.List

  • Array of java.util.Object

  • java.sql.ResultSet (which therefore also supports javax.sql.RowSet)

  • jakarta.servlet.jsp.jstl.sql.Result

  • java.util.Map (uses the wrapper for java.lang.Iterable by providing access to java.util.Map#entrySet())

  • Any other Java object is wrapped by a DataModel instance with a single row.[P1-end]

Convenience implementations of DataModel are provided in the jakarta.faces.model package for each of the above (see Concrete Implementations), and must be used by the UIData component to create the required DataModel wrapper.

4.1.3.3. Methods

UIData adds no new processing methods. However, the getDataModel() method is now protected, so implementations have access to the underlying data model. See NamingContainer for information about methods introduced by the implemented classes.

UIData specializes the behavior of the getClientId() method inherited from its parent, in order to create a client identifier that includes the current rowIndex value (if it is not -1). Because UIData is a NamingContainer, this makes it possible for rendered client identifiers of child components to be row-specific.

UIData specializes the behavior of the queueEvent() method inherited from its parent, to wrap the specified event (bubbled up from a child component) in a private wrapper containing the current rowIndex value, so that this rowIndex can be reset when the event is later broadcast.

UIData specializes the behavior of the broadcast() method to unwrap the private wrapper (if this event was wrapped), and call setRowIndex() to re-establish the context in which the event was queued, followed by delivery of the event.

[P1-start-uidataDecode]UIData specializes the behavior of the processDecodes(), processValidators(), and processUpdates() methods inherited from its parent as follows:

  • For each of these methods, the UIData implementation must iterate over each row in the underlying data model, starting with the row identified by the first property, for the number of rows indicated by the rows property, by calling the setRowIndex() method.

  • When iteration is complete, set the rowIndex property of this component, and of the underlying DataModel, to zero, and remove any request attribute exposed via the var property.[P1-end]

UIData specializes the behavior of invokeOnComponent() inherited from UIComponentBase to examine the argument clientId and extract the rowIndex, if any, and position the data properly before proceeding to locate the component and invoke the callback. Upon normal or exception return from the callback the data must be repositioned to match how it was before invoking the callback. Please see the javadocs for UIData.invokeOnComponent() for more details.

4.1.3.4. Events

UIData adds no new event handling methods. See NamingContainer for information about event handling introduced by the implemented classes.

4.1.4. UIForm

UIForm (extends UIComponentBase; implements NamingContainer) is a component that represents an input form to be presented to the user, and whose child components (among other things) represent the input fields to be included when the form is submitted.

[P1-start-uiformEncodeEnd]The encodeEnd() method of the renderer for UIForm must call ViewHandler.writeState() before writing out the markup for the closing tag of the form.[P1-end]This allows the state for multiple forms to be saved.

4.1.4.1. Component Type

The standard component type for UIForm components is “jakarta.faces.Form”.

4.1.4.2. Properties

UIForm adds the following render-independent properties.

Name Access Type Description

prependId

RW

boolean

If true, this UIForm instance does allow its id to be pre-pendend to its descendent’s id during the generation of clientIds for the descendents. The default value of this property is true.

[P1-start-uiform]UIForm specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Form”.

  • The default value of the rendererType property must be set to “jakarta.faces.Form”.[P1-end]

4.1.4.3. Methods.
public boolean isSubmitted();
public void setSubmitted(boolean submitted)

[P1-start-uiform-setSubmitted]The setSubmitted() method of each UIForm instance in the view must be called during the Apply Request Values phase of the request processing lifecycle, during the processing performed by the UIComponent.decode() method. If this UIForm instance represents the form actually being submitted on this request, the parameter must be set to true; otherwise, it must be set to false.[P1-end] The standard implementation of UIForm delegates the responsibility for calling this method to the Renderer associated with this instance..

[P1-start-uiform-submitted]The value of a UIForm's submitted property must not be saved as part of its state.[P1-end]

public void processDecodes(FacesContext context);

Override UIComponent.processDecodes() to ensure that the submitted property is set for this component. If the submitted property decodes to false, do not process the children and return immediately.

public void processValidators(FacesContext context);
public void processUpdates(FacesContext context);

Override processValidators() and processUpdates() to ensure that the children of this UIForm instance are only processed if isSubmitted() returns true.

public void saveState(FacesContext context);

[P1-start-uiformSaveState]The saveState() method of UIForm must call setSubmitted(false) before calling super.saveState() as an extra precaution to ensure the submitted state is not persisted across requests.[P1-end].

protected String getContainerClientId(FacesContext context);

[P1-start-uiformPrependId]Override the parent method to ensure that children of this UIForm instance in the view have the form’s clientId prepended to their clientIds if and only if the form’s prependId property is true.[P1-end]

4.1.4.4. Events

UIForm adds no new event handling methods.

4.1.5. UIGraphic

UIGraphic (extends UIComponentBase) is a component that displays a graphical image to the user. The user cannot manipulate this component; it is for display purposes only.

4.1.5.1. Component Type

The standard component type for UIGraphic components is “jakarta.faces.Graphic”.

4.1.5.2. Properties

The following render-independent properties are added by the UIGraphic component:

Name Access Type Description

url

RW

String

The URL of the image to be displayed. If this URL begins with a / character, it is assumed to be relative to the context path of the current web application. This property is a typesafe alias for the value property, so that the actual URL to be used can be acquired via a value expression.

value

RW

Object

The value of this component, normally used as a URL.

[P1-start-uigraphic]UIGraphic specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Graphic”.

  • The default value of the rendererType property must be set to “jakarta.faces.Image”.[P1-end]

4.1.5.3. Methods

UIGraphic adds no new processing methods.

4.1.5.4. Events

UIGraphic does not originate any standard events.

4.1.6. UIInput

UIInput (extends UIOutput, implements EditableValueHolder) is a component that both displays the current value of the component to the user (as UIOutput components do), and processes request parameters on the subsequent request that need to be decoded.

4.1.6.1. Component Type

The standard component type for UIInput components is “jakarta.faces.Input”.

4.1.6.2. Properties

UIInput adds the following renderer independent properties.:

Name Access Type Description

requiredMessage

RW

String

ValueExpression enabled property. If non-null, this property is used as the summary and detail strings of the FacesMessage that is queued on the FacesContext instead of the default message for the required validaiton failure. Note that the message is fully internationalizable via either the f:loadBundle tag or via ResourceBundle access from the EL.

converterMessage

RW

String

ValueExpression enabled property. If non-null, this property is used as the summary and detail strings of the FacesMessage that is queued on the FacesContext instead of the default message for conversion failure. Note that the message is fully internationalizable via either the f:loadBundle tag or via ResourceBundle access from the EL.

validatorMessage

RW

String

ValueExpression enabled property. If non-null, this property is used as the summary and detail strings of the FacesMessage that is queued on the FacesContext instead of the default message for validation failure. Note that the message is fully internationalizable via either the f:loadBundle tag or via ResourceBundle access from the EL.

See EditableValueHolder for information about properties introduced by the implemented interfaces.

[P1-start-uiinput]UIInput specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Input”.

  • The default value of the rendererType property must be set to “jakarta.faces.Text”.

  • The Converter specified by the converter property (if any) must also be used to perform String→Object conversions during decoding.[P1-end]

  • If the value property has an associated ValueExpression, the setValue() method of that ValueExpression will be called during the Update Model Values phase of the request processing lifecycle to push the local value of the component back to the corresponding model bean property.

4.1.6.3. Methods

The following method is used during the Update Model Values phase of the request processing lifecycle, to push the converted (if necessary) and validated (if necessary) local value of this component back to the corresponding model bean property.

public void updateModel(FacesContext context);

The following method is over-ridden from UIComponent:

public void broadcast(FacesEvent event);

In addition to the default UIComponent.broadcast(jakarta.faces.event.FacesEvent) processing, pass the ValueChangeEvent being broadcast to the method referenced by the valueChangeListener property (if any).

public void validate(FacesContext context);

Perform the algorithm described in the javadoc to validate the local value of this UIInput.

public void resetValue();

Perform the algorithm described in the javadoc to reset this UIInput to the state where it has no local value. This method does not touch the value expresson associated with the “value” property.

4.1.6.4. Events

All events are described in EditableValueHolder.

4.1.7. UIMessage

UIMessage (extends UIComponentBase) encapsulates the rendering of error message(s) related to a specified input component.

4.1.7.1. Component Type

The standard component type for UIMessage components is “jakarta.faces.Message”.

4.1.7.2. Properties

The following render-independent properties are added by the UIMessage component:

Name Access Type Description

for

RW

String

Identifier of the component for which to render error messages. If this component is within the same NamingContainer as the target component, this must be the component identifier. Otherwise, it must be an absolute component identifier (starting with “:”). See the UIComponent.findComponent() Javadocs for more information.

showDetail

RW

boolean

Flag indicating whether the “detail” property of messages for the specified component should be rendered. Default value is “true”.

showSummary

RW

boolean

Flag indicating whether the “summary” property of messages for the specified component should be rendered. Default value is “false”.

[P1-start-uimessage]UIMessage specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Message”.

  • The default value of the rendererType property must be set to “jakarta.faces.Message”.[P1-end]

4.1.7.3. Methods.

UIMessage adds no new processing methods.

4.1.7.4. Events

UIMessage adds no new event handling methods.

4.1.8. UIMessages

UIMessage (extends UIComponentBase) encapsulates the rendering of error message(s) not related to a specified input component, or all enqueued messages.

4.1.8.1. Component Type

The standard component type for UIMessages components is “jakarta.faces.Messages”.

4.1.8.2. Properties

The following render-independent properties are added by the UIMessages component:

Name Access Type Description

globalOnly

RW

boolean

Flag indicating whether only messages not associated with any specific component should be rendered. If not set, all messages will be rendered. Default value is “false”.

showDetail

RW

boolean

Flag indicating whether the “detail” property of messages for the specified component should be rendered. Default value is “false”.

showSummary

RW

boolean

Flag indicating whether the “summary” property of messages for the specified component should be rendered. Default value is “true”.

[P1-stat-uimessages]UIMessages specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Messages”.

  • The default value of the rendererType property must be set to “jakarta.faces.Messages”.[P1-end]

4.1.8.3. Methods.

UIMessages adds no new processing methods.

4.1.8.4. Events

UIMessages adds no new event handling methods.

4.1.9. UIOutcomeTarget

UIOutcomeTarget (UIOutput) is a component that has a value and an outcome, either which may optionally be retrieved from a model tier bean via a value expression (see Value Expressions), and is displayed to the user as a hyperlink, appearing in the form of a link or a button. The user cannot modify the value of the hyperlink, as it’s for display purposes only. The target URL of the hyperlink is derived by passing the outcome to the ConfigurationNavigationHandler to retrieve the matching NavigationCase and then using the ViewHandler to translate the NavigationCase into an action URL. When the client activates the hyperlink, typically by clicking it, the target URL is retrieved using a non-faces request and the response is rendered.

This component introduces a scenario known as "preemptive navigation". The navigation case is resolved during the Render Response phase, before the client activates the link (and may never activate the link). The predetermined navigation is pursued after the client activates the link. In contrast, the UICommand components resolve and execute the navigation at once, after the Invoke Application phase.

The UIOutcomeTarget component allows the developer to leverage the navigation model while at the same time being able to generate bookmarkable, non-faces requests to be included in the response.

4.1.9.1. Component Type

The standard component type for UIOutcomeTarget is "jakarta.faces.OutcomeTarget".

4.1.9.2. Properties

The following render-independent properties are added by thec component:

Name Access Type Description

Outcome

RW

String

The logical outcome that is used to resolve a NavigationCase which in turn is used to build the target URL of this component. Default value is the current view ID.

includePageParams

RW

boolean

Flag indicating whether the page parameters should be appended to the query string of the target URL. Default value is "false".

[P1-start-uioutcometarget] UIOutcomeTarget specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to "jakarta.faces.UIOutcomeTarget"

  • The default value of the rendererType property must be set to "jakarta.faces.Link" [P1-end]

4.1.9.3. Methods

The UIOutcomeTarget adds no event handling methods.

4.1.9.4. Events

The UIOutcomeTarget adds no event handling methods.

4.1.10. UIOutput

UIOutput (extends UIComponentBase; implements ValueHolder) is a component that has a value, optionally retrieved from a model tier bean via a value expression (see Value Expressions), that is displayed to the user. The user cannot directly modify the rendered value; it is for display purposes only:

4.1.10.1. Component Type

The standard component type for UIOutput components is “jakarta.faces.Output”.

4.1.10.2. Properties

UIOutput adds no new render-independent properties. See ValueHolder for information about properties introduced by the implemented classes.

[P1-start-uioutput]UIOutput specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Output”.

  • The default value of the rendererType property must be set to “jakarta.faces.Text”.[P1-end]

4.1.10.3. Methods

UIOutput adds no new processing methods. See ValueHolder for information about methods introduced by the implemented interfaces.

4.1.10.4. Events

UIOutput does not originate any standard events. See ValueHolder for information about events introduced by the implemented interfaces.

4.1.11. UIPanel

UIPanel (extends UIComponentBase) is a component that manages the layout of its child components.

4.1.11.1. Component Type

The standard component type for UIPanel components is “jakarta.faces.Panel”.

4.1.11.2. Properties

UIPanel adds no new render-independent properties.

[P1-start-uipanel]UIPanel specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Panel”.

  • The default value of the rendererType property must be set to null.[P1-end]

4.1.11.3. Methods

UIPanel adds no new processing methods.

4.1.11.4. Events

UIPanel does not originate any standard events

4.1.12. UIParameter

UIParameter (extends UIComponentBase) is a component that represents an optionally named configuration parameter that affects the rendering of its parent component. UIParameter components do not generally have rendering behavior of their own.

4.1.12.1. Component Type

The standard component type for UIParameter components is “jakarta.faces.Parameter”.

4.1.12.2. Properties

The following render-independent properties are added by the UIParameter component:

Name Access Type Description

name

RW

String

The optional name for this parameter.

value

RW

Object

The value for this parameter.

[P1-start-uiparameter]UIParameter specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.Parameter”.

  • The default value of the rendererType property must be set to null.[P1-end]

4.1.12.3. Methods

UIParameter adds no new processing methods.

4.1.12.4. Events

UIParameter does not originate any standard events

4.1.13. UISelectBoolean

UISelectBoolean (extends UIInput) is a component that represents a single boolean (true or false) value. It is most commonly rendered as a checkbox.

4.1.13.1. Component Type

The standard component type for UISelectBoolean components is “jakarta.faces.SelectBoolean”.

4.1.13.2. Properties

The following render-independent properties are added by the UISelectBoolean component:

Name Access Type Description

selected

RW

boolean

The selected state of this component. This property is a typesafe alias for the value property, so that the actual state to be used can be acquired via a value expression.

[P1-start-uiselectboolean]UISelectBoolean specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.SelectBoolean”.

  • The default value of the rendererType property must be set to “jakarta.faces.Checkbox”.[P1-end]

4.1.13.3. Methods

UISelectBoolean adds no new processing methods.

4.1.13.4. Events

UISelectBoolean inherits the ability to send ValueChangeEvent events from its parent UIInput component.

4.1.14. UISelectItem

UISelectItem (extends UIComponentBase) is a component that may be nested inside a UISelectMany or UISelectOne component, and represents exactly one SelectItem instance in the list of available options for that parent component.

4.1.14.1. Component Type

The standard component type for UISelectItem components is “jakarta.faces.SelectItem”.

4.1.14.2. Properties

The following render-independent properties are added by the UISelectItem component:

Name Access Type Description

itemDescription

RW

String

The optional description of this available selection item. This may be useful for tools.

itemDisabled

RW

boolean

Flag indicating that any synthesized SelectItem object should have its disabled property set to true.

itemLabel

RW

String

The localized label that will be presented to the user for this selection item.

itemValue

RW

Object

The server-side value of this item, of the same basic data type as the parent component’s value. If the parent component type’s value is a value expression that points at a primitive, this value must be of the corresponding wrapper type.

value

RW

jakarta.faces.model.SelectItem

The SelectItem instance associated with this component.

[P1-start-uiselectitem]UISelectItem specializes the behavior of render-independent properties inherited

  • The default value of the family property must be set to “jakarta.faces.SelectItem”.

  • The default value of the rendererType property must be set to null.

  • If the value property is non-null, it must contain a SelectItem instance used to configure the selection item specified by this component.

  • If the value property is a value expression, it must point at a SelectItem instance used to configure the selection item specified by this component.

  • If the value property is null, and there is no corresponding value expression, the itemDescription, itemDisabled, itemLabel and itemValue properties must be used to construct a new SelectItem representing the selection item specified by this component.[P1-end]

4.1.14.3. Methods

UISelectItem adds no new processing methods.

4.1.14.4. Events

UISelectItem does not originate any standard events.

4.1.15. UISelectItems

UISelectItems (extends UIComponentBase) is a component that may be nested inside a UISelectMany or UISelectOne component, and represents zero or more SelectItem instances for adding selection items to the list of available options for that parent component.

4.1.15.1. Component Type

The standard component type for UISelectItems components is “jakarta.faces.SelectItems”.

4.1.15.2. Properties

The following render-independent properties are added by the UISelectItems component:

Name Access Type Description

value

RW

See below

The SelectItem instances associated with this component.

[P1-start-uiselectitems]UISelectItems specializes the behavior of render-independent properties inherited

  • The default value of the family property must be set to “jakarta.faces.SelectItems”.

  • The default value of the rendererType property must be set to null.

  • If the value property (or the value returned by a value expression associated with the value property) is non-null, it must contain a SelectItem bean, an array of SelectItem beans, a Collection of SelectItem beans, or a Map, where each map entry is used to construct a SelectItem bean with the key as the label property of the bean, and the value as the value property of the bean (which must be of the same basic type as the value of the parent component’s value).[P1-end]

4.1.15.3. Methods

UISelectItems adds no new processing methods.

4.1.15.4. Events

UISelectItems does not originate any standard events.

4.1.16. UISelectMany

UISelectMany (extends UIInput) is a component that represents one or more selections from a list of available options. It is most commonly rendered as a combobox or a series of checkboxes.

4.1.16.1. Component Type

The standard component type for UISelectMany components is “jakarta.faces.SelectMany”.

4.1.16.2. Properties

The following render-independent properties are added by the UISelectMany component:

Name Access Type Description

selectedValues

RW

Object[] or array of primitives

The selected item values of this component. This property is a typesafe alias for the value property, so that the actual state to be used can be acquired via a value expression.

[P1-start-uiselectmany]UISelectMany specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.SelectMany”.

  • The default value of the rendererType property must be set to “jakarta.faces.Listbox”.[P1-end]

  • See the class Javadocs for UISelectMany for additional requirements related to implicit conversions for the value property.

4.1.16.3. Methods

[P1-start-uselectmany-validate]UISelectMany must provide a specialized validate() method which ensures that any decoded values are valid options (from the nested UISelectItem and UISelectItems children).[P1-end]

4.1.16.4. Events

UISelectMany inherits the ability to send ValueChangeEvent events from its parent UIInput component.

4.1.17. UISelectOne

UISelectOne (extends UIInput) is a component that represents zero or one selection from a list of available options. It is most commonly rendered as a combobox or a series of radio buttons.

4.1.17.1. Component Type

The standard component type for UISelectOne components is “jakarta.faces.SelectOne”.

4.1.17.2. Properties

UISelectOne adds no new render-independent properties.

[P1-start-uiselectone]UISelectOne specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.SelectOne”.

  • The default value of the rendererType property must be set to “jakarta.faces.Menu”.[P1-end]

4.1.17.3. Methods

[P1-start-uiselectone-validate]UISelectOne must provide a specialized validate() method which ensures that any decoded value is a valid option (from the nested UISelectItem and UISelectItems children).[P1-end]

4.1.17.4. Events

UISelectOne inherits the ability to send ValueChangeEvent events from its parent UIInput component.

4.1.18. UIViewParameter

UIViewParameter (extends UIInput) is a component that allows the query parameters included in the request by UIOutcomTarget renderers to participate in the lifecycle. Please see the javadocs for the normative speficication of this component.Events.

4.1.19. UIViewRoot

UIViewRoot (extends UIComponentBase;) represents the root of the component tree.

4.1.19.1. Component Type

The standard component type for UIViewRoot components is “jakarta.faces.ViewRoot

4.1.19.2. Properties

The following render-independent properties are added by the UIViewRoot component:

Name Access Type Description

locale

RW

java.util.Locale

The Locale to be used in localizing the response for this view.

renderKitId

RW

String

The id of the RenderKit used to render this page.

viewId

RW

String

The view identifier for this view.

beforePhaseListener

RW

MethodExpression

MethodExpression that will be invoked before all lifecycle phases except for Restore View.

afterPhaseListener

RW

MethodExpression

MethodExpression that will be invoked after all lifecycle phases except for Restore View.

viewMap

RW

java.util.Map

The Map that acts as the interface to the data store that is the "view scope".

For an existing view, the locale property may be modified only from the event handling portion of Process Validations phase through Invoke Application phase, unless it is modified by an Apply Request Values event handler for an ActionSource or EditableValueHolder component that has its immediate property set to true (which therefore causes Process Validations, Update Model Values, and Invoke Application phases to be skipped).

[P1-start-viewmap] The viewMap property is lazily created the first time it is accessed, and it is destroyed when a different UIViewRoot instance is installed from a call to FacesContext.setViewRoot(). After the Map is created a PostConstructViewMapEvent must be published using UIViewRoot as the event source. Immediately before the Map is destroyed, a PreDestroyViewMapEvent must be published using UIViewRoot as the event source. [P1-end]

[P1-start-uiviewroot]UIViewRoot specializes the behavior of render-independent properties inherited from the parent component as follows:

  • The default value of the family property must be set to “jakarta.faces.ViewRoot”.

  • The default value of the rendererType property must be set to null.[P1-end]

4.1.19.3. Methods

The following methods are used for adding UIComponent resources to a target area in the view, and they are also used for retrieving UIComponent resources from a target area in the view.

public void addComponentResource(FacesContext context,
    UIComponent componentResource);

Add componentResource, that is assumed to represent a resource instance, to the current view. A resource instance is rendered by a resource Renderer (such as ScriptRenderer, StylesheetRenderer) as described in the Standard HTML RenderKit. This method will cause the resource to be rendered in the “head” element of the view.

public void addComponentResource(FacesContext context,
    UIComponent componentResource, String target);

Add componentResource, that is assumed to represent a resource instance, to the current view at the specified target location. [P1-start-addComponentResource] The resource must be added using the algorithm outlined in this method’s Javadocs.[P1-end]

public List<UIComponent> getComponentResources(String target);

Return a List of UIComponent instances residing under the facet identified by target. Each UIComponent instance in the List represents a resource. [P1-start-getCompRes] The List must be formulated in accordance with this method’s Javadocs. [P1-end]

UIViewRoot specializes the behavior of the UIComponent.queueEvent() method to maintain a list of queued events that can be transmitted later. It also specializes the behavior of the processDecodes(), processValidators(), processUpdates(), and processApplication() methods to broadcast queued events to registered listeners. UIViewRoot clears any remaining events from the event queue in these methods if responseComplete() or renderResponse() has been set on the FacesContext. Please see Apply Request Values, Process Validations], Update Model Values and Invoke Application for more details.

4.1.19.4. Events

UIViewRoot is a source of PhaseEvent events, which are emitted when the instance moves through all phases of the request processing lifecycle except Restore View. This phase cannot emit events from UIViewRoot because the UIViewRoot instance isn’t created when this phase starts. See PhaseEvent and PhaseListener for more details on the event and listener class.

public void addPhaseListener(PhaseListener listener);
public void removePhaseListener(VPhaseListener listener);
public List<PhaseListener> getPhaseListeners();

[P1-start-events] UIViewRoot must listen for the top level PostAddToViewEvent event sent by the Restore View phase. Refer to Restore View for more details about the publishing of this event. Upon receiving this event, UIViewRoot must cause any “after” Restore View phase listeners to be called.[P1-end]

UIViewRoot is also the source for several kinds of system events. The system must publish a PostAddToViewEvent, with the UIViewRoot as the source, during the Restore View phase, immediately after the new UIViewRoot is set into the FacesContext for the request. The system must publish a PreRenderView event, with UIViewRoot as the source, during the Render Response phase, immediately before ViewHandler.renderView() is called.

4.1.19.5. Partial Processing

UIViewRoot adds special behavior to processDecodes, processValidators, processUpdates, getRendersChildren and encodeChildren to facilitate partial processing - namely the ability to have one or more components processed through the execute and/or render phases of the request processing lifecycle. Refer to Partial View Traversal, Partial View Processing, Partial View Rendering for an overview of partial processing. [P1-start-viewroot-partial] UIViewRoot must perform partial processing as outlined in the Javadocs for the “processXXX” and “encodeXXX” methods if the current request is a partial request.[P1-end]

4.2. Standard UIComponent Model Beans

Several of the standard UIComponent subclasses described in the previous section reference JavaBean components to represent the underlying model data that is rendered by those components. The following subsections define the standard UIComponent model bean classes.

4.2.1. DataModel

DataModel is an abstract base class for creating wrappers around arbitrary data binding technologies. It can be used to adapt a wide variety of data sources for use by Jakarta Server Faces components that want to support access to an underlying data set that can be modelled as multiple rows. The data underlying a DataModel instance is modelled as a collection of row objects that can be accessed randomly via a zero-relative index

4.2.1.1. Properties

An instance of DataModel supports the following properties:

Name Access Type Description

rowAvailable

RO

boolean

Flag indicating whether the current rowIndex value points at an actual row in the underlying data.

rowCount

RO

int

The number of rows of data objects represented by this DataModel instance, or -1 if the number of rows is unknown.

rowData

RO

Object

An object representing the data for the currently selected row. DataModel implementations must return an object that be successfully processed as the “base” parameter for the PropertyResolver in use by this application. If the current rowIndex value is -1, null is returned.

rowIndex

RW

int

Zero-relative index of the currently selected row, or -1 if no row is currently selected. When first created, a DataModel instance must return -1 for this property.

wrappedData

RW

Object

Opaque property representing the data object wrapped by this DataModel. Each individual implementation will restrict the types of Object(s) that it supports.

4.2.1.2. Methods

DataModel must provide an iterator() to iterate over the row data for this model.

4.2.1.3. Events

No events are generated for this component.

4.2.1.4. Concrete Implementations

[P1-start-datamodel]The Jakarta Faces implementation must provide concrete implementations of DataModel (in the jakarta.faces.model package) for the following data wrapping scenarios:

  • ArrayDataModel — Wrap an array of Java objects.

  • ListDataModel — Wrap a java.util.List of Java objects.

  • ResultDataModel — Wrap an object of type jakarta.servlet.jsp.jstl.sql.Result (the query results from JSTL’s SQL tag library)

  • ResultSetDataModel — Wrap an object of type java.sql.ResultSet (which therefore means that javax.sql.RowSet instances are also supported).

  • ScalarDataModel — Wrap a single Java object in what appears to be a one-row data set.

Each concrete DataModel implementation must extend the DataModel abstract base class, and must provide a constructor that accepts a single parameter of the object type being wrapped by that implementation (in addition to a zero-args constructor).[P1-end] See the JavaDocs for specific implementation requirements on DataModel defined methods, for each of the concrete implementation classes.

4.2.2. SelectItem

SelectItem is a utility class representing a single choice, from among those made available to the user, for a UISelectMany or UISelectOne component. It is not itself a UIComponent subclass.

4.2.2.1. Properties

An instance of SelectItem supports the following properties:

Name Access Type Description

description

RW

String

A description of this selection item, for use in development tools.

disabled

RW

boolean

Flag indicating that this option should be rendered in a fashion that disables selection by the user. Default value is false.

label

RW

String

Label of this selection item that should be rendered to the user.

value

RW

Object

The server-side value of this item, of the same basic data type as the parent component’s value. If the parent component type’s value is a value expression that points at a primitive, this value must be of the corresponding wrapper type.

4.2.2.2. Methods

An instance of SelectItem supports no additional public processing methods.

4.2.2.3. Events

An instance of SelectItem supports no events.

4.2.3. SelectItemGroup

SelectItemGroup is a utility class extending SelectItem, that represents a group of subordinate SelectItem instances that can be rendered as a “sub-menu” or “option group”. Renderers will typically ignore the value property of this instance, but will use the label property to render a heading for the sub-menu.

4.2.3.1. Properties

An instance of SelectItemGroup supports the following additional properties:

Name Access Type Description

selectItems

RW

SelectItem[]

Array of SelectItem instances representing the subordinate selection items that are members of the group represented by this SelectItemGroup instance.

Note that, since SelectItemGroup is a subclass of SelectItem, SelectItemGroup instances can be included in the selectItems property in order to create hierarchies of subordinate menus. However, some rendering environments may limit the depth to which such nesting is supported; for example, HTML/4.01 does not allow an <optgroup> to be nested inside another <optgroup> within a <select> control.

4.2.3.2. Methods

An instance of SelectItemGroup supports no additional public processing methods.

4.2.3.3. Events

An instance of SelectItemGroup supports no events.

5. Expression Language and Managed Bean Facility

In the descriptions of the standard user interface component model, it was noted that all attributes, and nearly all properties can have a value expression associated with them (see ValueExpression properties). In addition, many properties, such as action, actionListener, validator, and valueChangeListener can be defined by a method expression pointing at a public method in some class to be executed. This chapter describes the mechanisms and APIs that Jakarta Faces utilizes in order to evaluate value expressions and method expressions.

Jakarta Faces relies on Jakarta Expression Language as described by version 4.0 of the Jakarta Expression Language specification. Please consult that document for complete details about the Expression Language.

Versions 1.0 and 1.1 of pre-Jakarta Faces JSF under the JCP included a built in expression language and required an implementation of it. The API for this old JSF EL is still preserved as deprecated classes and methods, and Jakarta Faces implementations must still support that API. Please consult the Guide to Deprecated Methods Relating to the Expression Language and their Corresponding Replacements for details. This chapter will focus exclusively on how Jakarta Faces leverages and integrates with Jakarta Expression Language. It does not describe how Jakarta Expression Language operates.

5.1. Value Expressions

5.1.1. Overview

To support binding of attribute and property of values to dynamically calculated results, the name of the attribute or property can be associated with a value expression using the setValueExpression() method. Whenever the dynamically calculated result of evaluating the expression is required, the getValue() method of the ValueExpression is called, which returns the evaluated result. Such expressions can be used, for example, to dynamically calculate a component value to be displayed:

<h:outputText value=#{customer.name}/>

which, when this page is rendered, will retrieve the bean stored under the “customer” key, then acquire the name property from that bean and render it.

Besides the component value itself, value expressions can be used to dynamically compute attributes and properties. The following example checks a boolean property manager on the current user bean (presumably representing the logged-in user) to determine whether the salary property of an employee should be displayed or not:

<h:outputText rendered=#{user.manager} value=#{employee.salary}/>

which sets the rendered property of the component to false if the user is not a manager, and therefore causes this component to render nothing.

The Jakarta Expression Language has a powerful set of coercion rules that automatically convert the type of the value to the appropriate type. These rules occasionally rely on the JavaBeans PropertyEditor facility to perform this conversion. Note that this conversion is entirely separate from normal Jakarta Faces Conversion.

Value expressions can also be used to set a value from the user into the item obtained by evaluating the expression. For example:

<h:inputText value=#{employee.number}/>

When the page is rendered, the expression is evaluated as an r-value and the result is displayed as the default value in the text field. When the page is submitted, the expression is evaluated as an l-value, and the value entered by the user (subject to conversion and validation as usual) is pushed into the expression.

5.1.2. Value Expression Syntax and Semantics

Please see Section 1.2 of the Jakarta Expression Language Specification, Version 4.0 or higher for the complete specification of ValueExpression syntax and semantics.

5.2. MethodExpressions

Method expressions are a very similar to value expressions, but rather than supporting the dynamic retrieval and setting of properties, method expressions support the invocation (i.e. execution) of an arbitrary public method of an arbitrary object, passing a specified set of parameters, and returning the result from the called method (if any). They may be used in any phase of the request processing lifecycle; the standard Jakarta Faces components and framework employ them (encapsulated in a MethodExpression object) at the following times:

  • During Apply Request Values or Invoke Application phase (depending upon the state of the immediate property), components that implement the ActionSource2 behavioral interface (see ActionSource2) utilize MethodExpressions as follows:

    • If the actionExpression property is specified, it must be a MethodExpression expression that identifies an Application Action method (see Application Actions) that takes no parameters and returns a String.

    • It’s possible to have a method expression act as an ActionListener by using the classs MethodExpressionActionListener to wrap a method expression and calling the addActionListener() method on the ActionSource. The method expression wrapped inside the MethodExpressionActionListener must identify a public method that accepts an ActionEvent (see Event Classes) instance, and has a return type of void. The called method has exactly the same responsibilities as the processAction() method of an ActionListener instance (see Listener Classes) that was built in to a separate Java class.

  • During the Apply Request Values or Process Validations phase (depending upon the state of the immediate property), components that implement EditableValueHolder (such as UIInput and its subclasses) components (see EditableValueHolder) utilize method expressions as follows:

    • The user can use the MethodExpressionValidator class to wrap a method expression that identifies a public method that accepts a FacesContext instance and a UIComponent instance, and an Object containing the value to be validated, and has a return type of void. This MethodExpressionValidator instance can then be added as a normal Validator using the EditableValueHolder.addValidator() method. The called method has exactly the same responsibilities as the validate() method of a Validator instance (see Validator Classes) that was built in to a separate Java class.

    • The user can use the MethodExpressionValueChangeListener class to wrap a method expression that identifies a public method that accepts a ValueChangeEvent (see Event Classes) instance, and has a return type of void. This MethodExpressionValueChangeListener instance can then be added as a normal ValueChangeListener using EditableValueHolder.addValueChangeListener(). The called method has exactly the same responsibilities as the processValueChange() method of a ValueChangeListener instance (see Listener Classes) that was built in to a separate Java class.

Here is the set of component properties that currently support MethodBinding, and the method signatures to which they must point:

Table 2. component properties whose type is DEPRECATED MethodBinding
component property method signature

DEPRECATED action

public String <methodName>();

DEPRECATED actionListener

public void <methodName>(jakarta.faces.event.ActionEvent);

DEPRECATED validator

public void <methodName>(jakarta.faces.context.FacesContext, jakarta.faces.component.UIComponent, java.lang.Object)

DEPRECATED valueChangeListener

public void <methodName>(jakarta.faces.event.ValueChangeEvent);

Note that for any of the parameters for the above methods may also be a subclass of what is listed above. For the above properties that are marked as DEPRECATED, wrapper classes have been added that wrap a MethodExpression and implement the appropriate listener interface, allowing the wrapped expression to be added as a strongly typed listener, using the normal add*() pattern Here is the list of such wrapper classes:

Table 3. MethodExpression wrappers to take the place of DEPRECATED MethodBinding properties
component listener property Wrapper class method signature

actionListener

jakarta.faces.event.MethodExpressionActionListener

public void <methodName>(jakarta.faces.event.ActionEvent);

validator

jakarta.faces.validator.MethodExpressionValidator

public void <methodName>(jakarta.faces.context.FacesContext, jakarta.faces.component.UIComponent, java.lang.Object);

valueChangeListener

jakarta.faces.event.MethodExpressionValueChangeListener

public void <methodName>(jakarta.faces.event.ValueChangeEvent);

The MethodBinding typed action property of ActionSource is deprecated and has been replaced by the MethodExpression typed actionExpression property of ActionSource2.

5.2.1. MethodExpression Syntax and Semantics

The exact syntax and semantics of MethodExpression are the domain of the Jakarta Expression Language. Please see Section 1.2.1.2 of the Jakarta Expression Language Specification, Version 4.0 or higher.

5.3. The Managed Bean Facility

The use of the managed bean facility as specified in this section is strongly discouraged. A better and more cohesively integrated solution for solving the same problem is to use Contexts and Dependency Injection (CDI). (See Other Jakarta Platform Specifications).

Perhaps the biggest value-add of bringing Expression Language concepts to Jakarta Faces happens when the Expression Language is combined with the managed bean facility. This feature allows the user to configure an entire complex tree of POJO beans, including how they should be scoped and populated with initial values, and expose them to Expression Language expressions. Please see Managed Bean Configuration Example.

The Managed Bean Creation facility is configured by the existence of <managed-bean> elements in one or more application configuration resources (see Application Configuration Resources). Note that a special provision has been made for application configuration resource files residing within META-INF/managed-beans.xml entries on the application classpath. Please see Application Configuration Resource Format for the normative spec requirement. Such elements describe the characteristics of a bean to be created, and properties to be initialized, with the following nested elements:

  • <managed-bean-name> — The key under which the created bean can be retrieved; also the key in the scope under which the created bean will be stored, unless the value of <managed-bean-scope> is set to none.

  • <managed-bean-class> — The fully qualified class name of the application class used to instantiate a new instance. This class must conform to JavaBeans design patterns — in particular, it must have a public zero-args constructor, and must have public property setters for any properties referenced with nested <managed-property> elements — or it must be a class that implements java.util.Map or java.util.List.

  • <managed-bean-scope> — The scope ( request, view, session, or application) under which the newly instantiated bean will be stored after creation (under the key specified by the <managed-bean-name> element), or none for a bean that should be instantiated and returned, but not stored in any scope. The latter option is useful when dynamically constructing trees of related objects, as illustrated in the following example.
    The runtime must must allow the value of this element to be an EL ValueExpression. If so, and the expression evaluates to null, an informative error message including the expression string and the name of the bean must be logged. If the expression evaluates to a Map, that Map is used as the scope into which the bean will be stored. If storing the bean into the Map causes an Exception, the exception is allowed to flow up to the ExceptionHandler. If the ValueExpression does not evaluate to a Map, a FacesException must be thrown with a message that includes the expression string, the toString() of the value, and the type of the value.

  • <list-entries> or <map-entries> — Used to configure managed beans that are themselves instances of java.util.List or java.util.Map, respectively. See below for details on the contents of these elements.

  • <managed-property> — Zero or more elements used to initialize the properties of the newly instantiated bean (see below).

After the new managed bean instance is instantiated, but before it is placed into the specified scope (if any), each nested <managed-property> element must be processed and a call to the corresponding property setter must be made to initialize the value of the corresponding property. If the managed bean has properties not referenced by <managed-property> elements, the values of such properties will not be affected by the creation of this managed bean; they will retain whatever default values are established by the constructor.

Each <managed-property> element contains the following elements used to configure the execution of the corresponding property setter call:

  • <property-name> — The property name of the property to be configured. The actual property setter method to be called will be determined as described in the JavaBeans Specification.

  • Exactly one of the following sub-elements that can be used to initialize the property value in a number of different ways:

    • <map-entries> — A set of key/value pairs used to initialize the contents of a property of type java.util.Map (see below for more details).

    • <null-value/> — An empty element indicating that this property must be explicitly initialized to null. This element is not allowed if the underlying property is of a Java primitive type.

    • <value> — A String value that will have any leading and trailing spaces stripped, and then be converted (according to the rules described in the Jakarta Server Pages Specification for the <jsp:setProperty> action) to the corresponding data type of the property, prior to setting it to this value.

    • <list-entries> — A set of values used to initialize the contents of a property of type array or java.util.List See below for more information.

As described above, the <map-entries> element is used to initialize the key-value pairs of a property of type java.util.Map. This element may contain the following nested elements:

  • <key-class> — Optional element specifying the fully qualified class name for keys in the map to be created. If not specified, java.lang.String is used.

  • <value-class> — Optional element specifying the fully qualified class name for values in the map to be created. If not specified, java.lang.String is used.

  • <map-entry> — Zero or more elements that define the actual key-value pairs for a single entry in the map. Nested inside is a <key> element to define the key, and then exactly one of <null-value>, <value> to define the value. These elements have the same meaning as when nested in a <managed-property> element, except that they refer to an individual map entry’s value instead of the entire property value.

As described above, the <list-entries> element is used to initialize a set of values for a property of type array or java.util.List. This element may contain the following nested elements:

  • <value-class> — Optional element specifying the fully qualified class name for values in the map to be created. If not specified, java.lang.String is used.

  • Zero or more elements of type <null-value>, <value> to define the individual values to be initialized. These elements have the same meaning as when nested in a <managed-property> element, except that they refer to an individual list element instead of the entire property value.

The following general rules apply to the operation of the Managed Bean Creation facility:

  • Properties are assigned in the order that their <managed-property> elements are listed in the application configuration resource.

  • If a managed bean has writeable properties that are not mentioned in <managed-property> elements, the values of those properties are not assigned any values.

  • The bean instantiation and population with properties must be done lazily, when an Expression Language expression causes the bean to be referenced. For example, this is the case when a ValueExpression or MethodExpression has its getValue() or setValue() method called.

  • Due to the above mentioned laziness constraint, any error conditions that occur below are only required to be manifested at runtime. However, it is conceivable that tools may want to detect these errors earlier; this is perfectly acceptable. The presense of any of the errors described below, until the end of this section, must not prevent the application from deploying and being made available to service requests.

  • [P1-start managed bean config error conditions] It is an error to specify a managed bean class that does not exist, or that cannot be instantiated with a public, zero-args constructor.

  • It is an error to specify a <property-name> for a property that does not exist, or does not have a public setter method, on the specified managed bean class.

  • It is an error to specify a <value> element that cannot be converted to the type required by a managed property, or that, when evaluated, results in a value that cannot be converted to the type required by a managed property. [P1-end]

  • If the type of the property referenced by the <managed-property> element is a Java enum, the contents of the <value> element must be a String that yields a valid return from java.lang.Enum.valueOf(PROPERTY_CLASS, VALUE) where PROPERTY_CLASS is the java.lang.Class for the property and VALUE is the contents of the <value> element in the application configuration resource. If any exception is thrown from Enum.valueOf() it is an error.

  • [P1-start managed bean scope errors] It is an error for a managed bean created through this facility to have a property that points at an object stored in a scope with a (potentially) shorter life span. Specifically, this means, for an object created with the specified <managed-bean-scope>, then <value> evaluations can only point at created objects with the specified managed bean scope:

    • none — none

    • application — none, application

    • session — none, application, session

    • view — none, application, session, view

    • request — none, application, session, view, request [P1-end]

  • If a bean points to a property whose value is a mixed expression containing literal strings and expressions, the net scope of the mixed expression is considered to be the scope of the narrowest sub-expression, excluding expressions in the none scope.

  • [P1-start implicit objects in request scope] Data accessed via an implicit object is also defined to be in a scope. The following implicit objects are considered to be in request scope:

    • cookie

    • facesContext

    • header

    • headerValues

    • param

    • paramValues

    • request

    • requestScope

    • view [P1-end]

  • [P1-start implicit objects in session scope] The only implicit objects in session scope are session and sessionScope [P1-end]

  • [P1-start implicit objects in application scope] The following implicit objects are considered to be in application scope:

    • application

    • applicationScope

    • initParam [P1-end]

  • [P1-start cyclic references error] It is an error to configure cyclic references between managed beans.

  • [P1-start managed bean names correctness] Managed bean names must conform to the syntax of a Java language identifier. [P1-end]

The initialization of bean properties from <map-entries> and <list-entries> elements must adhere to the following algorithm, though any confirming implementation may be used.

For <map-entries>:

  1. Call the property getter, if it exists.

  2. If the getter returns null or doesn’t exist, create a java.util.HashMap, otherwise use the returned java.util.Map.

  3. Add all entries defined by nested <map-entry> elements in the order they are listed, converting key values defined by nested <key> elements to the type defined by <key-class> and entry values defined by nested <value> elements to the type defined by <value-class>. If a value is given as a value expression, evaluate the reference and store the result, converting to <value-class> if necessary. If <key-class> and/or <value-class> are not defined, use java.lang.String. Add null for each <null-value> element.

  4. If a new java.util.Map was created in step 2), set the property by calling the setter method, or log an error if there is no setter method.

For <list-entries>:

  1. Call the property getter, if it exists.

  2. If the getter returns null or doesn’t exist, create a java.util.ArrayList, otherwise use the returned Object (an array or a java.util.List).

  3. If a List was returned or created in step 2), add all elements defined by nested <value> elements in the order they are listed, converting values defined by nested <value> elements to the type defined by <value-class>. If a value is given as a value expression, evaluate the reference and store the result, converting to <value-class> if necessary. If a <value-class> is not defined, use the value as-is (i.e., as a java.lang.String). Add null for each <null-value> element.

  4. If an array was returned in step 2), create a java.util.ArrayList and copy all elements from the returned array to the new List, wrapping elements of a primitive type. Add all elements defined by nested <value> elements as described in step 3).

  5. If a new java.util.List was created in step 2) and the property is of type List, set the property by calling the setter method, or log an error if there is no setter method.

  6. If a new java.util.List was created in step 2) and the property is a java array, convert the List into an array of the property type, and set it by calling the setter method, or log an error if there is no setter method.

  7. If a new java.util.List was created in step 4), convert the List to an array of the proper type for the property and set the property by calling the setter method, or log an error if there is no setter method.

5.3.1. Managed Bean Configuration Example

The following <managed-bean> elements might appear in one or more application configuration resources (see Application Configuration Resources) to configure the behavior of the Managed Bean Creation facility.

Assume that your application includes CustomerBean with properties mailingAddress and shippingAddress of type Address (along with additional properties that are not shown), and AddressBean implementation classes with String properties of type street, city, state, country, and postalCode.

<managed-bean>
  <description>
    A customer bean will be created as needed, and stored in request
    scope. Its “mailingAddress” and “streetAddress” properties will
    be initialized by virtue of the fact that the “value” expressions
    will not encounter any object under key “addressBean” in any scope.
  </description>
  <managed-bean-name>customer</managed-bean-name>
  <managed-bean-class>
    com.mycompany.mybeans.CustomerBean
  </managed-bean-class>
  <managed-bean-scope>request</managed-bean-scope>
  <managed-property>
    <property-name>mailingAddress</property-name>
    <value>#{addressBean}</value>
  </managed-property>
  <managed-property>
    <property-name>shippingAddress</property-name>
    <value>#{addressBean}</value>
  </managed-property>
  <managed-property>
    <property-name>customerType</property-name>
    <value>New</value> <!-- Set to literal value -->
  </managed-property>
</managed-bean>
<managed-bean>
  <description>
    A new AddressBean will not be added to any scope, because we
    only want to create instances when a CustomerBean creation asks
    for them. Therefore, we set the scope to “none”.
  </description>
  <managed-bean-name>addressBean</managed-bean-name>
  <managed-bean-class>
    com.mycompany.mybeans.AddressBean
  </managed-bean-class>
  <managed-bean-scope>none</managed-bean-scope>
</managed-bean>

If a value expression “#{customer.mailingAddress.city}” were to be evaluated by the Jakarta Faces implementation, and there was no object stored under key “customer” in request, view, session, or application scope, a new CustomerBean instance will be created and stored in request scope, with its mailingAddress and shippingAddress properties being initialized to instances of AddressBean as defined by the configuration elements shown above. Then, the evaluation of the remainder of the expression can proceed as usual.

Although not used by the Jakarta Faces implementation at application runtime, it is also convenient to be able to indicate to Jakarta Faces tools (at design time) that objects of particular types will be created and made available (at runtime) by some other means. For example, an application configuration resource could include the following information to declare that a JDBC data source instance will have been created, and stored in application scope, as part of the application’s own startup processing.

<referenced-bean>
  <description>
    A JDBC data source will be initialized and made available in
    some scope (presumably application) for use by the Jakarta Faces based
    application when it is actually run. This information is not
    used by the Jakarta Faces implementation itself; only by tools.
  </description>
  <referenced-bean-name>dataSource</referenced-bean-name>
  <referenced-bean-class>
    javax.sql.DataSource
  </referenced-bean-class>
</referenced-bean>

This information can be utilized by the tool to construct user interfaces based on the properties of the referenced beans.

5.4. Managed Bean Annotations

Jakarta Faces has several annotations, in the package jakarta.faces.bean, that act as analogs to the managed bean configuration syntax in the application configuration resources described earlier in this chapter. Jakarta Faces is a component specification of Jakarta EE, which also includes a much more powerful and complete set of annotations, from several other component specifications, most notably Jakarta Contexts and Dependency Injection (CDI). These annotations are also usable with Jakarta Faces. The annotations in the package jakarta.faces.bean are deprecated. Therefore, developers are strongly recommended to avoid using those annotations and instead use the ones from CDI.

5.4.1. Jakarta Faces Managed Classes and Jakarta EE Annotations

Jakarta Faces implementations that are running as a part of Jakarta EE must allow managed bean implementations to use the annotations specified in section 14.5 of the Jakarta Servlet Specification to allow the container to inject references to container managed resources into a managed bean instance before it is made accessible to the Jakarta Faces application. Only beans declared to be in request, session, or application scope are eligible for resource injection.

In addition to managed beans being injectable in this manner, the following Jakarta Faces artifacts are also injectable.

Jakarta Faces Artifacts Eligible for Injection

Artifact Type

  • jakarta.el.ELResolver

  • jakarta.faces.application.ApplicationFactory

  • jakarta.faces.application.NavigationHandler

  • jakarta.faces.application.ResourceHandler

  • jakarta.faces.application.StateManager

  • jakarta.faces.component.visit.VisitContextFactory

  • jakarta.faces.context.ExceptionHandlerFactory

  • jakarta.faces.context.ExternalContextFactory

  • jakarta.faces.context.FacesContextFactory

  • jakarta.faces.context.PartialViewContextFactory

  • jakarta.faces.event.ActionListener

  • jakarta.faces.event.SystemEventListener

  • jakarta.faces.lifecycle.ClientWindowFactory

  • jakarta.faces.lifecycle.LifecycleFactory

  • jakarta.faces.event.PhaseListener

  • jakarta.faces.render.RenderKitFactory

  • jakarta.faces.view.ViewDeclarationLanguageFactory

  • jakarta.faces.view.facelets.FaceletCacheFactory

  • jakarta.faces.view.facelets.
    TagHandlerDelegateFactory

Please consult the Jakarta EE Specification for complete details of this feature. Here is a summary of the Jakarta EE annotations one may use in a managed bean or other artifact from the preceding table. [P1-start valid annotations in a managed bean]

  • @jakarta.inject.Inject

  • @jakarta.inject.Named

  • @jakarta.inject.Qualifier

  • @jakarta.inject.Scope

  • @jakarta.inject.Singleton

  • @jakarta.enterprise.context.ApplicationScoped

  • @jakarta.enterprise.context.ConversationScoped

  • @jakarta.enterprise.context.Dependent

  • @jakarta.enterprise.context.RequestScoped

  • @jakarta.enterprise.context.SessionScoped

  • @jakarta.annotation.Resource

  • @jakarta.annotation.Resources

  • @jakarta.ejb.EJB

  • @jakarta.ejb.EJBs

  • @jakarta.xml.ws.WebServiceRef

  • @jakarta.xml.ws.WebServiceRefs

  • @jakarta.persistence.PersistenceContext

  • @jakarta.persistence.PersistenceContexts

  • @jakarta.persistence.PersistenceUnit

  • @jakarta.persistence.PersistenceUnits

Following is an example of valid usages of this feature in a managed bean or other artifact in the preceding table.

public class User extends Object {
  private @EJB ShoppingCart cart;
  private @Resource Inventory inventory;
  private DataSource customerData;

  @Resource(name=customerData)
  private void setCustomerData(DataSource data) {
    customerData = data;
  }

  public String getOrderSummary() {
    // Do something with the injected resources
    // And generate a textual summary of the order
  }
}

This example illustrates that the above annotations can be attached to instance variables or to JavaBeans setters. The Jakarta Faces implementation running in a Jakarta EE container must guarantee that the injections are performed before the bean is handed back to the user. Generally, this is done by performing the injection immediately after the lazy instantiation of the managed bean.

5.4.2. Managed Bean Lifecycle Annotations

Jakarta Faces implementations running in a Jakarta EE compliant container must support attaching the @PostConstruct and @PreDestroy annotations to aid in awareness of the managed-bean lifecycle.

Methods on managed beans declared to be in none, request, view, session, or application scope, annotated with @PostConstruct, must be called by the Jakarta Faces implementation after resource injection is performed (if any) but before the bean is placed into scope.

[P1-start rules governing invocation of @PostConstruct annotated methods]If the method throws an unchecked exception, the Jakarta Faces implementation must not put the managed-bean into service, a message must be logged, and further methods on that managed bean instance must not be called. [P1-end]

Methods on managed beans declared to be in request, session, or application scope, annotated with @PreDestroy, must be called by the Jakarta Faces implementation before the bean is removed from its scope or before the scope itself is destroyed, whichever comes first. In the case of a managed bean placed in view scope, methods annotated with @PreDestroy must only be called when the view scope is destroyed. See the javadoc for FacesContext.setViewRoot(). This annotation must be supported in all cases where the above @PostConstruct annotation is supported.

[P1-start rules governing invocation of @PreDestroy annotated methods] If the method throws an unchecked exception, the Jakarta Faces implementation may log it, but the exception must not otherwise alter the execution.

Refer to the Jakarta EE specification section 2.5 and the Jakarta Annotations specification section 2.5 for more details.[P1-end]

5.5. How Faces Leverages the Expression Language

This section is non-normative and covers the major players in the Jakarta Expression Language and how they relate to Jakarta Faces. The number one goal in this version of the Jakarta Faces specification is to export the concepts behind the Jakarta Faces EL into the Jakarta Expression Language, and then rely on those facilities to get the work done. Readers interested in how to implement the Jakarta Expression Language itself must consult the Jakarta Expression Language Spec document.

5.5.1. ELContext

The ELContext is a handy little “holder” object that gets passed all around the Jakarta Expression Language API. It has two purposes.

  • To allow technologies that use the Jakarta Expression Language , such as Jakarta Faces, the Jakarta Faces View Declaration Language, and Jakarta Server Pages, to store any context information specific to that technology so it can be leveraged during expression evaluation. For example the expression “${view.viewId}” is specific to Jakarta Faces. It means, “find the UIViewRoot instance for the current view, and return its viewId”. The Jakarta Expression Language doesn’t know about the “view” implicit object or what a UIViewRoot is, but Jakarta Faces does. The Jakarta Expression Language has plugin points that will get called to resolve “view”, but to do so, Jakarta Faces needs access to the FacesContext from within the callstack of Expression Language evaluation. Therefore, the ELContext comes to the rescue, having been populated with the FacesContext earlier in the request processing lifecycle.

  • To allow the pluggable resolver to tell the Jakarta Expression Language that it did, in fact, resolve a property and that further resolvers must not be consulted. This is done by setting the “propertyResolved” property to true.

The complete specification for ELResolver may be found in Chapter 2 of the Jakarta Expression Language Specification, Version 4.0.

5.5.1.1. Lifetime, Ownership and Cardinality

An ELContext instance is created the first time getELContext() is called on the FacesContext for this request. Please see ELContext for details. Its lifetime ends the same time the FacesContext’s lifetime ends. The FacesContext maintains the owning reference to the ELContext. There is at most one ELContext per FacesContext.

5.5.1.2. Properties
Name Access Type Description

ELResolver

RO

jakarta.el.ELResolver

Return the ELResolver instance described in Faces ELResolver for Jakarta Server Pages Pages

propertyResolved

RW

boolean

Set by an ELResolver implementation if it successfully resolved a property. See ELResolver for how this property is used.

5.5.1.3. Methods

Here is a subset of the methods that are relevant to Jakarta Faces.

public Object getContext(Class key);
void putContext(Class key, Object contextInstance);
...

As mentioned in ELContext, the putContext() method is called, passing the current FacesContext instance the first time the system asks the FacesContext for its ELContext. The getContext() method will be called by any ELResolver instances that need to access the FacesContext to perform their resolution.

5.5.1.4. Events

The creation of an ELContext instance precipitates the emission of an ELContextEvent from the FacesContext that created it. Please see ELContext for details.

5.5.2. ELResolver

Faces 1.1 used the VariableResolver and PropertyResolver classes as the workhorses of expression evaluation. The Unified API has the ELResolver instead. The ELResolver concept is the heart of the Jakarta Expression Language. When an expression is evaluated, the ELResolver is responsible for resolving each segment in the expression. For example, in rendering the component behind the tag “<h:outputText value=”#{user.address.street}” />” the ELResolver is called three times. Once to resolve “user”, again to resolve the “address” property of user, and finally, to resolve the “street” property of “address”. The complete specification for ELResolver may be found in Chapter 2 of the Jakarta Expression Language Specification, Version 4.0 or higher.

[N/T-start two ELResolver impls] As described in more detail in Faces ELResolver for Jakarta Server Pages Pages, Faces must provide two implementations of ELResolver. [P1-end]Which of these two implementations is actually used to resolve an expression depends on where the expresison is evaluated. If the expression is evaluated in a markup page, the ELResolver for markup pages is used. If the expression is evaluated in java VM hosted code from Faces, another ELResolver is used that is tailored for use inside of Faces java VM hosted code. During the course of evaluation of an expression, a variety of sources must be considered to help resolve each segment of the expression. These sources are linked in a chain-like fashion. Each link in the chain has the opportunity to resolve the current segment. If it does so, it must set the “propertyResolved” property on the ELContext, to true. If not, it must not modify the value of the “propertyResolved” property. If the “propertyResolved” property is not set to true the return value from the ELResolver method is ignored by the system.

5.5.2.1. Lifetime, Ownership, and Cardinality

ELResolver instances have application lifetime and scope. The Jakarta Server Pages container maintains one top level ELResolver (into which a Faces specific ELResolver is added) accessible from JspContext.getELContext().getELResolver(). This ELResolver instance is also used from the Jakarta Faces VDL, even though Jakarta Faces VDL pages do not themselves use Jakarta Server Pages. Faces maintains one ELResolver (separate from the one handed to the Jakarta Server Pages container) accessible from FacesContext.getELContext().getELResolver() and Application.getELResolver().

5.5.2.2. Properties

ELResolver has no proper JavaBeans properties

5.5.2.3. Methods

Here is a subset of the methods that are relevant to Faces.

public Object getValue(ELContext context, Object base, Object property);
void setValue(ELContext context,
    Object base, Object property, Object value);
...

getValue() looks at the argument base and tries to return the value of the property named by the argument property. For example, if base is a JavaBean, property would be the name of the JavaBeans property, and the resolver would end up calling the getter for that property.

setValue() looks at the argument base and tries to set the argument value into the property named by the argument property. For example, if base is a JavaBean, property would be the name of the JavaBeans property, and the resolver would end up calling the setter for that property.

There are other methods, such as isReadOnly() that are beyond the scope of this document, but described completely in the Jakarta Expression Language Specification.

5.5.2.4. Events

ELResolver precipitates no events.

5.5.3. ExpressionFactory

Pre-Jakarta Faces JSF 1.1 (under the JCP) used the Application class as a factory for ValueBinding and MethodBinding instances. The Jakarta Expression Language has the ExpressionFactory class instead. It is a factory for ValueExpression and MethodExpression instances.

5.5.3.1. Lifetime, Ownership, and Cardinality

ExpressionFactory instances are application scoped. The Application object maintains the ExpressionFactory instance used by Faces (See Acquiring ExpressionFactory Instance). The JspApplicationContext object maintains the ExpressionFactory used by the Jakarta Server Pages container (and therefore by the Jakarta Faces VDL). It is permissible for both of these access methods to yield the same java object instance.

5.5.3.2. Properties

ExpressionFactory has no properties.

5.5.3.3. Methods
public MethodExpression createMethodExpression(ELContext context,
    String expression, FunctionMapper fnMapper, Class[] paramTypes);
public ValueExpression createValueExpression(ELContext context,
    String expression, Class expectedType, FunctionMapper fnMapper);

These methods take the human readable expression string, such as ”#{user.address.street}” and return an object oriented representation of the expression. Which method one calls depends on what kind of expression you need. The Faces Application class has convenience methods specific to Faces needs for these concepts, please see Programmatically Evaluating Expressions .

5.5.3.4. Events

ExpressionFactory precipitates no events.

5.6. ELResolver Instances Provided by Faces

This section provides details on what an implementation of the Jakarta Server Faces specification must do to support the Jakarta Expression Language for usage in a Jakarta Faces application.

ELResolver mentions that a Faces implementation must provide two implementations of ELResolver. One ELResolver, let’s call it the Faces ELResolver For Markup Pages, is plugged in to the top level resolver chain returned from JspContext.getELContext().getELResolver(). This top level resolver chain is used by the view declaration language container (Jakarta Server Pages or Jakarta Faces View Declaration Language), and possibly by tag handlers, to resolve expressions. The other ELResolver, let’s call it the ELResolver for Facelets and Programmatic Access, is used by Facelets markup pages, and is returned from FacesContext.getELContext().getELResolver() and Application.getELResolver(), and is used to resolve expressions that appear programmatically. See the javadocs for jakarta.el.ELResolver for the specification and method semantics for each method in ELResolver. The remainder of this section lists the implementation requirements for these two resolvers.

5.6.1. Faces ELResolver for Jakarta Server Pages Pages

As mentioned in ELResolver, during the course of evaluation of an expression, a variety of sources must be considered to help resolve each segment of the expression. These sources are linked in a chain-like fashion. Each link in the chain has the opportunity to resolve the current segment. The Jakarta Expression Language provides a container class to support this multi-source variable resolution: jakarta.el.CompositeELResolver. The implementation for the Faces ELResolver for Jakarta Server Pages Pages is described as a set of ELResolvers inside of a CompositeELResolver instance, but any implementation strategy is permissible as long as the semantics are preserved.

This diagram shows the set of ELResolver instances that must be added to the Faces ELResolver for Jakarta Server Pages pages. This instance must be handed to the Jakarta Server Pages container via a call to JspFactory.getDefaultFactory().getJspApplicationContext().addELResolver() at application startup time. Even though we are making a Jakarta Server Pages API call to install this ELResolver, we do not require using Jakarta Server Pages to develop Jakarta Faces applications. It also shows the order in which they must be added. [P2-start there are 18 methods in the below tables, each can corresponding to a method on a particular ELResolver. With clever testing, it is possible to write assertions for these. Testing the legacy VariableResolver and PropertyResolvers is not included in this 18 methods number. These classes may be tested simply by noting that the methods do indeed get called on a user-provided VariableResolver or PropertyResolver.] [P1-end]

Faces ELResolver for Jakarta Server Pages Pages

image

The semantics of each ELResolver are given below, either in tables that describe what must be done to implement each particular method on ELResolver, or in prose when such a table is inappropriate.

5.6.1.1. Faces Implicit Object ELResolver For Jakarta Server Pages

This resolver relies on the presence of another, Jakarta Server Pages specific, implicit object ELResolver in the chain by only resolving the “facesContext” and “view” implicit objects.

Table 4. Faces ImplicitObjectELResolver for Jakarta Server Pages
ELResolver method implementation requirements

getValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

See ImplicitObjectELResolver for Programmatic Access If base is null and property is a String equal to “facesContext”, call setPropertyResolved(true) on the argument ELContext and return the FacesContext for this request.

If base is null and property is a String equal to “view”, call setPropertyResolved(true) on the argument ELContext and return the UIViewRoot for this request by calling facesContext.getUIViewRoot().

This ELResolver must also support the implicit object “resource” as specified in Implicit Object ELResolver for Facelets and Programmatic Access

getType

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to “facesContext” or “view”, call setPropertyResolved(true) and return null;

Otherwise, just return null;This ELResolver must also support the implicit object “resuorce” as specified in Implicit Object ELResolver for Facelets and Programmatic Access

setValue

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to “facesContext” or “view”, throw jakarta.el.PropertyNotWriteable, since “view” and “facesContext” are read-only. This ELResolver must also support the implicit object “resuorce” as specified in Implicit Object ELResolver for Facelets and Programmatic Access

isReadOnly

If base is non-null, return false.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to “facesContext” or “view”, call setPropertyResolved(true) on the argument ELContext and return true.

Otherwise return false;This ELResolver must also support the implicit object “resuorce” as specified in Implicit Object ELResolver for Facelets and Programmatic Access

getFeatureDescriptors

If base is non-null, return null.

If base is null, return an Iterator containing three java.beans.FeatureDescriptor instances, one for the “view” property, one for the “facesContext” property and one for the “resource” property. It is required that all of the FeatureDescriptor instances in the Iterator set Boolean.TRUE as the value of the ELResolver.RESOLVABLE_AT_DESIGN_TIME attribute. The name and displayName of the FeatureDescriptor must be “view”, “facesContext”, “ or “resource” as appropriate. FacesContext.class, UIViewRoot.class, or ResourceHandler.class must be stored as the value of the ELResolver.TYPE attribute, as approriate. The shortDescription must be a suitable description depending on the implementation. The expert and hidden properties must be false. The preferred property must be true.

getCommonPropertyType

If base is non-null, return null.

If base is null and return String.class.

5.6.1.2. ManagedBean ELResolver

This is the means by which the managed bean creation facility described in The Managed Bean Facility is called into play during Expression Language resolution.

Table 5. ManagedBeanELResolver
ELResorver method implementation requirements

getValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If property matches the name of an entry in the request, session, or application scopes, in that order, return null.

If base is null, and property matches one of the managed-bean-name declarations in the application configuration resources, instantiate the bean, populate it with properties as described in The Managed Bean Facility, store it in the scope specified by the managed-bean-scope declaration for this this managed-bean, call setPropertyResolved(true) on the argument ELContext, and return the freshly instantiated managed-bean.

Otherwise, return null.

getType

If base is null and property is null, throw PropertyNotFoundException.

Otherwise return null;

setValue

If base is null and property is null, throw PropertyNotFoundException.

Otherwise, if base is null, and property matches one of the managed-bean-name declarations in the application configuration resources, and a managed bean with that managed-bean-name does not yet exist in the specified scope, instantiate the bean, populate it with properties as described in The Managed Bean Facility, store it in the scope specified by the managed-bean-scope declaration for this this managed-bean and return. If the managed bean does exist, take no action and return. In either case (the bean exists or does not exist), the actual setting will happen by virtue of the BeanELResolver.

Otherwise take no action and return.

isReadOnly

If base is non-null, return false.

If base is null and property is null, throw PropertyNotFoundException.

If base is null return false. We never set the propertyResloved property in this method because the set responsibility is taken care of by the ScopedAttributeELResolver.

getFeatureDescriptors

If base is non-null, return null.

If base is null, return an Iterator containing java.beans.FeatureDescriptor instances for each managed-bean in the application-configuration resources. It is required that all of the FeatureDescriptor instances in the Iterator set Boolean.TRUE as the value of the ELResolver.RESOLVABLE_AT_DESIGN_TIME attribute. The name and displayName of the FeatureDescriptor must be the managed-bean-name. The actual java Class instance for the managed-bean-class must be stored as the value of the ELResolver.TYPE attribute. The shortDescription of the FeatureDescriptor must be the description of the managaged-bean element, if present, null otherwise. The expert and hidden properties must be false. The preferred property must be true.

getCommonPropertyType

If base is non-null, return null.

If base is null, return Object.class.

5.6.1.3. Resource ELResolver

Please see Resource ELResolver for the specification of this ELResolver.

5.6.1.4. ResourceBundle ELResolver for Jakarta Server Pages Pages

This is the means by which resource bundles defined in the application configuration resources are called into play during Expression Language resolution.

Table 6. ResourceBundleELResolver
ELResorver method implementation requirements

getValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to the value of the <var> element of one of the <resource-bundle>'s in the application configuration resources, use the Locale of the current UIViewRoot and the base-name of the resource-bundle to load the ResourceBundle. Call setPropertyResolved(true). Return the ResourceBundle. Otherwise, return null.

getType

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to the value of the <var> element of one of the <resource-bundle>'s in the application configuration resources, call setPropertyResolved(true) and return ResourceBundle.class.

setValue

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to the value of the <var> element of one of the <resource-bundle>'s in the application configuration resources throw jakarta.el.PropertyNotWriteable, since ResourceBundles are read-only.

isReadOnly

If base is non-null, return null.

If base is false and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to the value of the <var> element of one of the <resource-bundle>'s in the application configuration resources, call setPropertyResolved(true) on the argument ELContext and return true.

Otherwise return false;

getFeatureDescriptors

If base is non-null, return null.

If base is null, return an Iterator containing java.beans.FeatureDescriptor instances, one for each <resource-bundle> in the <application> element. It is required that all of these FeatureDescriptor instances set Boolean.TRUE as the value of the ELResolver.RESOLVABLE_AT_DESIGN_TIME attribute. The name of the FeatureDescriptor must be the var element of the <resource-bundle>. The displayName of the FeatureDescriptor must be the display-name of the <resource-bundle>. ResourceBundle.class must be stored as the value of the ELResolver.TYPE attribute. The shortDescription must be a suitable description depending on the implementation. The expert and hidden properties must be false. The preferred property must be true.

getCommonPropertyType

If base is non-null, return null.

If base is null, return string.Class.

5.6.1.5. ELResolvers in the application configuration resources

The <el-resolver> element in the application configuration resources will contain the fully qualified classname to a class with a public no-arg constructor that implements jakarta.el.ELResolver. These are added to the Faces ELResolver for Jakarta Server Pages Pages and the Faces ELResolver for Facelets and Programmatic Access in the order in which they occur in the application configuration resources.

5.6.1.6. VariableResolver Chain Wrapper

This is the means by which VariableResolver instances that have been specified in <variable-resolver> elements inside the application configuration resources are allowed to affect the EL resolution process. If there are one or more <variable-resolver> elements in the application configuration resources, an instance of ELResolver with the following semantics must be created and added to the Faces ELResolver for Jakarta Server Pages Pages as indicated in the Faces ELResolver for Jakarta Server Pages Pages.

By virtue of the decorator pattern described in Delegating Implementation Support , the default VariableResolver will be at the end of the VariableResolver chain (See VariableResolver and the Default VariableResolver), if each custom VariableResolver chose to honor the full decorator pattern. If the custom VariableResolver chose not to honor the decorator pattern, the user is stating that they want to take over complete control of the variable resolution system. Note that the head of the VariableResolver chain is no longer accessible by calling Application.getVariableResolver() (Please see VariableResolver Property for what it returns). The head of the VariableResolver chain is kept in an implementation specific manner.

The semantics of the ELResolver that functions as the VariableResolver chain wrapper are described in the following table.

Table 7. ELResolver that is the VariableResolver Chain Wrapper
ELResorver method implementation requirements

getValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

Otherwise, call setPropertyResolved(true) on the argument ELContext.

Get the ELContext from the FacesContext.

Get the head of the VariableResolver chain and call resolveVariable(facesContext, property) and return the result.

Catch any exceptions that may be thrown by resolveVariable(), call setPropertyResolved(false) on the argument ELContext, and rethrow the exception wrapped in an jakarta.el.ELException.

getType

If base is null and property is null, throw PropertyNotFoundException.

return null;

setValue

If base is null and property is null throw PropertyNotFoundException.

isReadOnly

If base is null and property is null throw PropertyNotFoundException.

return false;

getFeatureDescriptors

return null;

getCommonPropertyType

If base is null, we return String.class.

If base is non-null, return null;

5.6.1.7. PropertyResolver Chain Wrapper

This is the means by which propertyResolver instances that have been specified in <property-resolver> elements inside the application configuration resources are allowed to affect the EL resolution process. If there are one or more <property-resolver> elements in the application configuration resources, an instance of ELResolver with the following semantics must be created and added to the Faces ELResolver for Jakarta Server Pages Pages as indicated in the Faces ELResolver for Jakarta Server Pages Pages.

By virtue of the decorator pattern described in Delegating Implementation Support, the default propertyResolver will be at the end of the propertyResolver chain (See, PropertyResolver and the Default PropertyResolver), if each custom propertyResolver chose to honor the full decorator pattern. If the custom propertyResolver chose not to honor the decorator pattern, then the user is stating that they want to take over complete control of the propertyResolution system. Note that the head of the propertyResolver chain is no longer accessible by calling Application.getPropertyResolver() (Please see PropertyResolver Property for what it returns). The head of the property resolver chain is kept in an implementation specific manner.

The semantics of the ELResolver that functions as the property resolver chain wrapper are described in the following table.

Table 8. ELResolver that is the PropertyResolver Chain Wrapper
ELResorver method implementation requirements

getValue,

getType,

isReadOnly,

setValue

If base or property are null, return null (or false if the method returns boolean).

Call setPropertyResolved(true) on the argument ELContext.

Get the ELContext from the FacesContext.

Get the head of the propertyResolver chain.

If base is a List or java language array, coerce the property to an int and call the corresponding method on the head of the property resolver chain that takes an int for property, returning the result (except in the case of setValue()).

Otherwise, call the corresponding method on the head of the property resolver chain that takes an Object for property, returning the result (except in the case of setValue()).

If an Exception is thrown by calling the above methods on the PropertyResolver chain, catch it, call setPropertyResolved(false) on the argument ELContext, and rethrow the Exception wrapped (snuggly) in a jakarta.el.ELException.

getFeatureDescriptors

return null;

getCommonPropertyType

If base is null, return null.

If base is non-null, return Object.class.

5.6.1.8. ELResolvers from Application.addELResolver()

Any such resolvers are considered at this point in the Faces ELResolver for Jakarta Server Pages Pages in the order in which they were added.

5.6.2. ELResolver for Facelets and Programmatic Access

This section documents the requirements for the second ELResolver mentioned in ELResolver Instances Provided by Faces, the one that is used for Facelets and for programmatic expression evaluation from Faces java code.

The implementation for the ELResolver for Programmatic Access is described as a set of ELResolvers inside of a CompositeELResolver instance, but any implementation strategy is permissible as long as the semantics are preserved. .

This diagram shows the set of ELResolver instances that must be added to the ELResolver for Programmatic Access. This instance must be returned from Application.getELResolver() and FacesContext.getELContext().getELResolver(). It also shows the order in which they must be added. [P1-state there are 12 methods in the below tables that can be tested for assertion. The remainder of the section is covered by the tests in 5.6.1][P1-end]

ELResolver for Facelets and Programmatic Access

image

The semantics of each ELResolver are given below, either in tables that describe what must be done to implement each particular method on ELResolver, in prose when such a table is inappropriate, or as a reference to another section where the semantics are exactly the same.

5.6.2.1. Implicit Object ELResolver for Facelets and Programmatic Access

This resolver differs from the one in the Faces Implicit Object ELResolver For Jakarta Server Pages in that it must resolve all of the implicit objects, not just facesContext and view

Table 9. ImplicitObjectELResolver for Programmatic Access
ELResolver method implementation requirements

getValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to implicitObject, call setPropertyResolved(true) on the argument ELContext and return result, where implicitObject and result are as follows:

implicitObject result

application

externalContext.getContext()

applicationScope

externalContext.getApplicationMap()

cookie

externalContext.getRequestCookieMap()

facesContext

the FacesContext for this request

component

the top of the stack of UIComponent instances, as pushed via calls to UIComponent.pushComponentToEL(). See Lifecycle Management Methods

flowScope

facesContext.getApplication().getFlowHandler().getCurrentFlowScope()

cc

the current composite component relative to the declaring page in which the expression appears.

flash

externalContext.getFlash()

header

externalContext.getRequestHeaderMap()

headerValues

externalContext.getRequestHeaderValuesMap()

initParam

externalContext.getInitParameterMap()

param

externalContext.getRequestParameterMap()

paramValues

externalContext.getRequestParameterValuesMap()

request

externalContext.getRequest()

requestScope

externalContext.getRequestMap()

resource

facesContext.getApplication().getResourceHandler()

session

externalContext.getSession()

sessionScope

externalContext.getSessionMap()

view

facesContext.getViewRoot()

viewScope

facesContext.getViewRoot().getViewMap()

resource

facesContext.getApplication().getResourceHandler()

If base is null, and property doesn’t match one of the above implicitObjects, return null.

getType

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to “application”, “component”, “cc”, “cookie”, “facesContext”, “header”, “headerValues”, “initParam”, “param”, “paramValues”, “request”, “resource”, “session”, or “view”, call setPropertyResolved(true) on the argument ELContext and return null to indicate that no types are accepted to setValue() for these attributes.

If base is null and property is a String equal to “requestScope”, “sessionScope”, or “applicationScope”, call setPropertyResolved(true) on the argument ELContext and return null.

Otherwise, null;

setValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to “applicationScope”, “requestScope”, “sessionScope”, “application”, “component”, “cc”, “cookie”, “facesContext”, “header”, “headerValues”, “initParam”, “param”, “paramValues”, “request”, “resource”, “session”, or “view”, throw jakarta.el.PropertyNotWriteableException, since these implicit objects are read-only.

Otherwise return null.

isReadOnly

If base is non-null, return (or false if the method returns boolean).

If base is null and property is null, throw PropertyNotFoundException.

If base is null and property is a String equal to “applicationScope”, “component”, “cc”, “requestScope”, “sessionScope”, “application”, “cookie”, “facesContext”, “header”, “headerValues”, “initParam”, “param”, “paramValues”, “request”, “resource”, “session”, or “view”, call setPropertyResolved(true) on the argument ELContext and return true.

Otherwise return null.

getFeatureDescriptors

If base is non-null, return null.

If base is null, return an Iterator containing 17 java.beans.FeatureDescriptor instances, one for eath of the following properties: application, component, cc, cookie, facesContext, header, headerValues, initParam, param, paramValues, request, resource, session, view, applicationScope, sessionScope, and requestScope. It is required that all of these FeatureDescriptor instances set Boolean.TRUE as the value of the ELResolver.RESOLVABLE_AT_DESIGN_TIME attribute. For the name and short of FeatureDescriptor, return the implicit object name. The appropriate Class must be stored as the value of the ELResolver.TYPE attribute as follows:

implicitObject ELResolver.TYPE value

application

Object.class

applicationScope

Map.class

component

UIComponent.class

cc

UIComponent.class

cookie

Map.class

facesContext

FacesContext.class

header

Map.class

headerValues

Map.class

initParam

Map.class

param

Map.class

paramValues

Map.class

request

Object.class

resource

Object.class

requestScope

Map.class

session

Object.class

sessionScope

Map.class

view

UIViewRoot.class

The shortDescription must be a suitable description depending on the implementation. The expert and hidden properties must be false. The preferred property must be true.

getCommonPropertyType

If base is non-null, return null.

If base is null and return String.class

5.6.2.2. Composite Component Attributes ELResolver

This ELResolver makes it so expressions that refer to the attributes of a composite component get correctly evaluated. For example, the expression #{cc.attrs.usernameLabel} says, “find the current composite component, call its getAttributes() method, within the returned Map look up the value under the key “usernameLable”. If the value is a ValueExpression, call getValue() on it and the result is returned as the evaluation of the expression. Otherwise, if the value is not a ValueExpression the value itself is returned as the evaluation of the expression.”

Table 10. Composite Component Attributes ELResolver
ELResolver method implementation requirements

getValue

If base is non-null, is an instance of UIComponent, is a composite component, and property is non-null and is equal to the string “attrs”, return a Map implementation with the following characteristics.

Wrap the attributes map of the composite component and delegate all calls to the composite component attributes map with the following exceptions:

get(), put(), and containsKey() are required to be supported.

get(): if the result of calling get() on the component attributes map is null, and a default value was declared in the composite component metadata, the value will be a ValueExpression. Evaluate it and return it. Otherwise, simply return the value from the component attributes map.

put(): Call getValueExpression() on the component. If this returns non-null, call setValue() on it, passing the value argument as the last argument. Otherwise, simply call through to put on the component attributes map.

containsKey(): If the attributes map contains the key, return true. Otherwise, if a default value has been declared for the attribute, return true. Otherwise, return false.

The Map implementation must also implement the interface

jakarta.faces.el.CompositeComponentExpressionHolder.

Otherwise, take no action.

getType

If the base argument to getType() is not an instance of the composite component attributes map or the property argument to getType() is not an instance of java.lang.String, return null. Otherwise, check the top level component’s ValueExpression collection for an expression under the name given by the property argument to getType(). If the expression exists, call getType() on the expression. If the property argument to getType() is not empty, search the composite component’s metadata for a declared type on a <composite:attribute> whose name matches the property argument to getType(). If the expression and the metadata both yield results, the metadata takes precedence ONLY if it provides a narrower result than does the expression, i.e. expression type is assignable from metadata type. If the metadata result does take precedence, call ELContext.setPropertyResolved(true). Otherwise, return whichever result was available, or null.

setValue

Take no action.

isReadOnly

Take no action and return true.

getFeatureDescriptors

Take no action.

getCommonPropertyType

Return String.class

5.6.2.3. The CompositeELResolver

As indicated in ELResolver for Facelets and Programmatic Access, following the ImplicitObjectELResolver, the semantics obtained by adding a CompositeELResolver must be inserted here. This ELResolver contains the following ELResolvers, described in the referenced sections.

5.6.2.4. ManagedBean ELResolver

This resolver has the same semantics as the one in ManagedBean ELResolver.

5.6.2.5. Resource ELResolver

This resolver is a means by which Resource instances are encoded into a faces request such that a subsequent faces resource request from the browser can be satisfied using the ResourceHandler as described in Resource Handling.

Table 11. ResourceELResolver
ELResorver method implementation requirements

getValue

If base and property are not null, and base is an instance of ResourceHandler (as will be the case with an expression such as #\{resource[‘ajax.js’]}, perform the following. (Note: This is possible due to the ImplicitObjectELResolver returning the ResourceHandler, see Implicit Object ELResolver for Facelets and Programmatic Access)

  • If property does not contain a colon character ‘:’, treat property as the resourceName and pass property to ResourceHandler.createResource(resourceName).

  • If property contains a single colon character ‘:’, treat the content before the ‘:’ as the libraryName and the content after the ‘:’ as the resourceName and pass both to ResourceHandler.createResource(resourceName, libraryName). If the value of libraryName is the literal string “this” (without the quotes), discover the library name of the current resource (or the contract name of the current resource, the two are mutually exclusive) and replace “this” with that library name (or contract name) before calling ResourceHandler.createResource(). In the case of resource library contracts, libraryName will actually be the contract name.

  • If property contains more than one colon character ‘:’, throw a localized ELException, including property.

If one of the above steps results in the creation of a non-null Resource instance, call ELContext.setPropertyResolved(true). Call the getRequestPath() method on the Resource instance, pass the result through ExternalContext.encodeResourceUrl() and return the result.

getType

Return null. This resolver only performs lookups.

setValue

Take no action.

isReadOnly

Return false in all cases.

getFeatureDescriptors

Return null.

getCommonPropertyType

If base is non-null, return null.

If base is null, return Object.class.

5.6.2.6. el.ResourceBundleELResolver

This entry in the chain must have the semantics the same as the class jakarta.el.ResourceBundleELResolver. The default implementation just includes an instance of this resolver in the chain.

5.6.2.7. ResourceBundle ELResolver for Programmatic Access

This resolver has the same semantics as the one in ResourceBundle ELResolver for Jakarta Server Pages pages.

5.6.2.8. Stream, StaticField, Map, List, Array, and Bean ELResolvers

These ELResolver instances are provided by the Jakarta Expression Language API and must be added in the following order:

[P1-start_EL_3_0] If running on a container that supports Jakarta Expression Language 4.0 or higher: The return from ExpressionFactory.getStreamELResolver, jakarta.el.StaticFieldELResolver. [P1-end_EL_3_0]

jakarta.el.MapELResolver, jakarta.el.ListELResolver, jakarta.el.ArrayELResolver, jakarta.el.BeanELResolver. These actual ELResolver instances must be added. It is not compliant to simply add other resolvers that preserve these semantics.

5.6.2.9. ScopedAttribute ELResolver

This ELResolver is responsible for doing the scoped lookup that makes it possible for expressions to pick up anything stored in the request, session, or application scopes by name.

Table 12. Scoped Attribute ELResolver
ELResorver method implementation requirements

getValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

Use the argument property as the key in a call to externalContext.getRequestMap().get(). If this returns non-null, call setPropertyResolved(true) on the argument ELContext and return the value.

Use the argument property as the key in a call to facesContext.getViewRoot().getViewMap().get() (accounting for the potential for null returns safely). If this returns non-null, call setPropertyResolved(true) on the argument ELContext and return the value.

Use the argument property as the key in a call to externalContext.getSessionMap().get(). If this returns non-null, call setPropertyResolved(true) on the argument ELContext and return the value.

Use the argument property as the key in a call to externalContext.getApplicationMap().get(). If this returns non-null, call setPropertyResolved(true) on the argument ELContext and return the value.

Otherwise call setPropertyResloved(true) and return null;

getType

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

Otherwise, setPropertyResolved(true) and return Object.class to indicate that any type is permissable to pass to a call to setValue().

setValue

If base is non-null, return null.

If base is null and property is null, throw PropertyNotFoundException.

Consult the Maps for the request, session, and application, in order, looking for an entry under the key property. If found, replace that entry with argument value. If not found, call externalContext.getRequestMap().put(property, value).

Call setPropertyResolved(true) and return;

isReadOnly

If base is false, setPropertyResolved(true) return false;

Otherwise, return false;

getFeatureDescriptors

If base is non-null, return null.

If base is null, return an Iterator of java.beans.FeatureDescriptor instances for all attributes in all scopes. The FeatureDescriptor name and shortName is the name of the scoped attribute. The actual runtime type of the attribute must be stored as the value of the ELResolver.TYPE attribute. Boolean.TRUE must be set as the value of the ELResolver.RESOLVABLE_AT_DESIGN_TIME attribute. The shortDescription must be a suitable description depending on the implementation. The expert and hidden properties must be false. The preferred property must be true.

getCommonPropertyType

If base is non-null, return null.

If base is null return String.class.

5.6.3. CDI for Expression Language Resolution

If the any of the managed beans in the application have the @jakarta.faces.annotation.FacesConfig annotation, the ImplicitObjectELResolver from Implicit Object ELResolver for Facelets and Programmatic Access is not present in the chain. Instead, CDI is used to perform Expression Language resolution in the same manner is in ImplicitObjectELResolver for Programmatic Access with the following additional implicit objects:

  • externalContext

  • the current ExternalContext from the current FacesContext

5.7. Current Expression Evaluation APIs

5.7.1. ELResolver

This class is the Jakarta Expression Language’s answer to Faces’s VariableResolver and PropertyResolver. It turns out that variable resolution can be seen as a special case of property resolution with the base object being null. Please see ELResolver for more details.

5.7.2. ValueExpression

This class is the Jakarta Expression Language’s answer to Jakarta Faces’s ValueBinding. It is the main object oriented abstraction for an Expression Language expression that results in a value either being retrieved or set. Please see Chapter 2 of the Jakarta Expression Language Specification, Version 4.0 or higher.

5.7.3. MethodExpression

This class is the Jakarta Expression Language’s answer to Jakarta Faces’s MethodBinding. It is the main object oriented abstraction for an Expression Language expression that results in a method being invoked. Please see Chapter 2 of the Jakarta Expression Language Specification, Version 4.0 or higher.

5.7.4. Expression Evaluation Exceptions

Four exception classes are defined to report errors related to the evaluation of value exceptions:

  • jakarta.el.ELException (which extends java.lang.Exception)—used to report a problem evaluating a value exception dynamically.

  • MethodNotFoundException (which extends jakarta.el.ELException)—used to report that a requested public method does not exist in the context of evaluation of a method expression.

  • jakarta.el.PropertyNotFoundException (which extends jakarta.el.ELException)—used to report that a requested property does not exist in the context of evaluation of a value expression.

  • jakarta.el.PropertyNotWriteableException (which extends jakarta.el.ELException)—used to indicate that the requested property could not be written to when evaluating the expression.

5.8. Deprecated Expression Evaluation APIs

Applications written for version 1.0 and 1.1 of the Faces specification must continue to run in this version of the specification. This means deprecated APIs. This section describes the migration story for these APIs that implementations must follow to allow 1.0 and 1.1 based applications to run.

5.8.1. VariableResolver and the Default VariableResolver

User-provided VariableResolver instances will still continue to work by virtue of VariableResolver Chain Wrapper. The decorator pattern described in Delegating Implementation Support must be supported. Users wishing to affect Expression Language resolution are advised to author a custom ELResolver instead. These will get picked up as specified in ELResolvers in the application configuration resources.

The Jakarta Faces implementation must provide a default VariableResolver implementation that gets the ELContext from the argument FacesContext and calls setPropertyResolved(false) on it

The VariableResolver chain is no longer accessible from Application.getVariableResolver(). The chain must be kept in an implementation dependent manner, but accessible to the ELResolver described in VariableResolver Chain Wrapper.

5.8.2. PropertyResolver and the Default PropertyResolver

User-provided propertyResolver instances will still continue to work by virtue of VariableResolver Chain Wrapper. The decorator pattern described in Delegating Implementation Support must be supported. Users wishing to affect Expression Language resolution are advised to author a custom ELResolver instead. These will get picked up as specified in ELResolvers in the application configuration resources.

The Jakarta Faces implementation must provide a default propertyResolver implementation that gets the ELContext from the argument FacesContext and calls setPropertyResolved(false) on it.

The PropertyResolver chain is no longer accessible from Application.getpropertyResolver(). The chain must be kept in an implementation dependent manner, but accessible to to the ELResolver described in PropertyResolver Chain Wrapper.

5.8.3. ValueBinding

The ValueBinding class encapsulates the actual evaluation of a value binding. Instances of ValueBinding for specific references are acquired from the Application instance by calling the createValueBinding method (see Acquiring ValueBinding Instances).

public Object getValue(FacesContext context)
    throws EvaluationException, PropertyNotFoundException;

Evaluate the value binding used to create this ValueBinding instance, relative to the specified FacesContext, and return the referenced value.

public void setValue(FacesContext context, Object value)
    throws EvaluationException, PropertyNotFoundException;

Evaluate the value binding used to create this ValueBinding instance, relative to the specified FacesContext, and update the referenced value to the specified new value.

public boolean isReadOnly(FacesContext context)
    throws EvaluationException, PropertyNotFoundException;

Evaluate the value binding used to create this ValueBinding instance, relative to the specified FacesContext, and return true if the corresponding property is known to be immutable. Otherwise, return false.

public Class getType(FacesContext context)
    throws EvaluationException, PropertyNotFoundException;

Evaluate the value binding used to create this ValueBinding instance, relative to the specified FacesContext, and return the Class that represents the data type of the referenced value, if it can be determined. Otherwise, return null.

5.8.4. MethodBinding

The MethodBinding class encapsulates the actual evaluation of a method binding. Instances of MethodBinding for specific references are acquired from the Application instance by calling the createMethodBinding() method. Note that instances of MethodBinding are immutable, and contain no references to a FacesContext (which is passed in as a parameter when the reference binding is evaluated).

public Object invoke(FacesContext context, Object params[])
    throws EvaluationException, MethodNotFoundException;

Evaluate the method binding (see MethodExpression Syntax and Semantics) and call the identified method, passing the specified parameters. Return any value returned by the invoked method, or return null if the invoked method is of type void.

public Class getType(FacesContext context) throws MethodNotFoundException;

Evaluate the method binding (see MethodExpression Syntax and Semantics) and return the Class representing the return type of the identified method. If this method is of type void, return null instead.

5.8.5. Expression Evaluation Exceptions

Four exception classes are defined to report errors related to the evaluation of value exceptions [Note that these exceptions are deprecated]:

  • EvaluationException (which extends FacesException)—used to report a problem evaluating a value exception dynamically.

  • MethodNotFoundException (which extends EvaluationException)—used to report that a requested public method does not exist in the context of evaluation of a method expression.

  • PropertyNotFoundException (which extends EvaluationException)—used to report that a requested property does not exist in the context of evaluation of a value expression.

  • ReferenceSyntaxException (which extends EvaluationException)—used to report a syntax error in a value exception.

5.9. CDI Integration

Jakarta Faces must run in a container that supports CDI version 3.0 or higher. This requirement allows CDI to provide all the functionality of the managed bean facility from The Managed Bean Facility and Managed Bean Annotations but in a better integrated way with the rest of the Jakarta EE platform. Delegating these features to CDI allows them to evolve independently of Jakarta Faces. The remainder of this section specifies some details of CDI integration pertinent to Jakarta Faces.

5.9.1. Jakarta Faces Objects Valid for @Inject Injection

It must be possible to inject the following Jakarta Faces objects into other objects using @Inject.

Maps Returned by Various Jakarta Faces Accessors

The annotations in package jakarta.faces.annotation are used to cause @Inject injection of the corresponding Map into a field. Generics may be used.

Jakarta Faces Objects

It must be possible to @Inject the following Jakarta Faces and Jakarta EE objects into CDI beans.

  • jakarta.faces.application.ResourceHandler

  • jakarta.faces.context.ExternalContext

  • jakarta.faces.context.FacesContext

  • jakarta.faces.context.Flash

  • jakarta.servlet.http.HttpSession

Support for Injection into Jakarta Faces Managed Objects

It must be possible to use @Inject when specifying the following kinds of Jakarta Faces managed objects.

  • Validators declared with @jakarta.faces.validator.FacesValidator(managed=”true”)

  • Converters declared with @jakarta.faces.convert.FacesConverter(managed=”true”)

  • FacesBehaviors declared with @jakarta.faces.component.behavior.FacesBehavior(managed=”true”)

5.9.2. Expression Language Resolution

The following implicit objects must be resolved using CDI

  • application

  • cc

  • component

  • facesContext

  • flash

  • flowScope

  • header

  • headerValues

  • initParam

  • param

  • paramValues

  • session

  • view

  • viewScope

6. Per-Request State Information

During request processing for a Jakarta Faces page, a context object is used to represent request-specific information, as well as provide access to services for the application. This chapter describes the classes which encapsulate this contextual information.

6.1. FacesContext

Jakarta Faces defines the jakarta.faces.context.FacesContext abstract base class for representing all of the contextual information associated with processing an incoming request, and creating the corresponding response. A FacesContext instance is created by the Jakarta Faces implementation, prior to beginning the request processing lifecycle, by a call to the getFacesContext method of FacesContextFactory, as described in FacesContextFactory. When the request processing lifecycle has been completed, the Jakarta Faces implementation will call the release method, which gives Jakarta Faces implementations the opportunity to release any acquired resources, as well as to pool and recycle FacesContext instances rather than creating new ones for each request.

6.1.1. Application

public Application getApplication();

[P1-start-application]The Jakarta Faces implementation must ensure that the Application instance for the current web application is available via this method, as a convenient alternative to lookup via an ApplicationFactory.[P1-end]

6.1.2. Attributes

public Map<Object,Object> getAttributes();

[P1-start-attributes]Return a mutable Map representing the attributes associated wth this FacesContext instance. This Map is useful to store attributes that you want to go out of scope when the Faces lifecycle for the current request ends, which is not always the same as the request ending, especially in the case of Servlet filters that are invoked after the Faces lifecycle for this request completes. Accessing this Map does not cause any events to fire, as is the case with the other maps: for request, session, and application scope.[P1-end]

6.1.3. ELContext

public ELContext getELContext();

Return the ELContext instance for this FacesContext instance. This ELContext instance has the same lifetime and scope as the FacesContext instance with which it is associated, and may be created lazily the first time this method is called for a given FacesContext instance. [P1-start-elcontext]Upon creation of the ELContext instance, the implementation must take the following action:

  • Call the ELContext.putContext(java.lang.Class, java.lang.Object) method on the instance, passing in FacesContext.class and the this reference for the FacesContext instance itself.

  • If the Collection returned by jakarta.faces.Application.getELContextListeners() is non-empty, create an instance of ELContextEvent and pass it to each ELContextListener instance in the Collection by calling the ELContextListener.contextCreated(jakarta.el.ELContextEvent) method.[P1-end]

6.1.4. ExternalContext

It is sometimes necessary to interact with APIs provided by the containing environment in which the Jakarta Server Faces application is running. In most cases this is the servlet API, but it is also possible for a Jakarta Server Faces application to run inside of a portlet. Jakarta Server Faces provides the ExternalContext abstract class for this purpose. [P1-start-externalContext]This class must be implemented along with the FacesContext class, and must be accessible via the getExternalContext method in FacesContext.[P1-end]

public ExternalContext getExternalContext();

[P1-start externalContext during Init] The default implementation must return a valid value when this method is called during startup time. See the javadocs for this method for the complete specification. [P1-end]

The ExternalContext instance provides immediate access to all of the components defined by the containing environment (servlet or portlet) within which a Jakarta Faces-based web application is deployed. The following table lists the container objects available from ExternalContext. Note that the Access column refers to whether the returned object is mutable. None of the properties may be set through ExternalContext. itself.

Name Access Type Description

applicationMap

RW

java.util.Map

The application context attributes for this application.

authType

RO

String

The method used to authenticate the currently logged on user (if any).

context

RW

Object

The application context object for this application.

initParameterMap

RO

java.util.Map

The context initialization parameters for this application

remoteUser

RO

String

The login name of the currently logged in user (if any).

request

RW

Object

The request object for this request.

requestContextPath

RO

String

The context path for this application.

requestCookieMap

RO

java.util.Map

The cookies included with this request.

requestHeaderMap

RO

java.util.Map

The HTTP headers included with this request (value is a String).

requestHeaderValuesMap

RO

java.util.Map

.The HTTP headers included with this request (value is a String array).

requestLocale

RW

java.util.Locale

The preferred Locale for this request.

requestLocales

RW

java.util.Iterator

The preferred Locales for this request, in descending order of preference.

requestMap

RW

java.util.Map

The request scope attributes for this request.

requestParameterMap

RO

java.util.Map

The request parameters included in this request (value is a String).

requestParameterNames

RO

Iterator

The set of request parameter names included in this request.

requestParameterValuesMap

RO

java.util.Map

The request parameters included in this request (value is a String array).

requestPathInfo

RO

String

The extra path information from the request URI for this request.

requestServletPath

RO

String

The servlet path information from the request URI for this request.

response

RW

Object

The response object for the current request.

sessionMap

RW

java.util.Map

The session scope attributes for this request5.

userPrincipal

RO

java.security.Principal

The Principal object containing the name of the currently logged on user (if any).

See the JavaDocs for the normative specification.

6.1.4.1. Flash

The Flash provides a way to pass temporary objects between the user views generated by the faces lifecycle. Anything one places in the flash will be exposed to the next view encountered by the same user session and then cleared out..

Name Access Type Description

flash

R

Flash

See the javadocs for the complete specification.

6.1.5. ViewRoot

public UIViewRoot getViewRoot();
public void setViewRoot(UIViewRoot root);

During the Restore View phase of the request processing lifecycle, the state management subsystem of the Jakarta Faces implementation will identify the component tree (if any) to be used during the inbound processing phases of the lifecycle, and call setViewRoot() to establish it.

6.1.6. Message Queue

public void addMessage(String clientId, FacesMessage message);

During the Apply Request Values, Process Validations, Update Model Values, and Invoke Application phases of the request processing lifecycle, messages can be queued to either the component tree as a whole (if clientId is null), or related to a specific component based on its client identifier.

public Interator<String> getClientIdsWithMessages();
public Severity getMaximumSeverity();
public Iterator<FacesMessage> getMessages(String clientId);
public Iterator<FacesMessage> getMessages();

[P1-start-messageQueue]The getClientIdsWithMessages() method must return an Iterator over the client identifiers for which at least one Message has been queued. This method must be implemented so the clientIds are returned in the order of calls to addMessage().[P1-end] The getMaximumSeverity() method returns the highest severity level on any Message that has been queued, regardless of whether or not the message is associated with a specific client identifier or not. The getMessages(String) method returns an Iterator over queued Messages, either those associated with the specified client identifier, or those associated with no client identifier if the parameter is null. The getMessages() method returns an Iterator over all queued Messages, whether or not they are associated with a particular client identifier. Both of the getMessage() variants must be implemented such that the messages are returned in the order in which they were added via calls to addMessage().

For more information about the Message class, see FacesMessage.

6.1.7. RenderKit

public RenderKit getRenderKit();

Return the RenderKit associated with the render kit identifier in the current UIViewRoot (if any).

6.1.8. ResponseStream and ResponseWriter

public ResponseStream getResponseStream();
public void setResponseStream(ResponseStream responseStream);
public ResponseWriter getResponseWriter();
public void setResponseWriter(ResponseWriter responseWriter);
public void enableResponseWriting(boolean enable);

Jakarta Faces supports output that is generated as either a byte stream or a character stream. UIComponents or Renderer s that wish to create output in a binary format should call getResponseStream() to acquire a stream capable of binary output. Correspondingly, UIComponents or Renderers that wish to create output in a character format should call getResponseWriter() to acquire a writer capable of character output.

Due to restrictions of the underlying servlet APIs, either binary or character output can be utilized for a particular response—they may not be mixed.

Please see ViewHandler to learn when setResponseWriter() and setResponseStream() are called.

The enableResponseWriting method is useful to enable or disable the writing of content to the current ResponseWriter instance in this FacesContext. [P1-start-enableWriting]If the enable argument is false, content should not be written to the response if an attempt is made to use the current ResponseWriter.

6.1.9. Flow Control Methods

public void renderResponse();
public void responseComplete();
public boolean getRenderResponse();
public boolean getResponseComplete();

Normally, the phases of the request processing lifecycle are executed sequentially, as described in Request Processing Lifecycle. However, it is possible for components, event listeners, and validators to affect this flow by calling one of these methods.

The renderResponse() method signals the Jakarta Faces implementation that, at the end of the current phase (in other words, after all of the processing and event handling normally performed for this phase is completed), control should be transferred immediately to the Render Response phase, bypassing any intervening phases that have not yet been performed. For example, an event listener for a tree control that was designed to process user interface state changes (such as expanding or contracting a node) on the server would typically call this method to cause the current page to be redisplayed, rather than being processed by the application.

The responseComplete() method, on the other hand, signals the Jakarta Faces implementation that the HTTP response for this request has been completed by some means other than rendering the component tree, and that the request processing lifecycle for this request should be terminated when the current phase is complete. For example, an event listener that decided an HTTP redirect was required would perform the appropriate actions on the response object (i.e. calling ExternalContext.redirect()) and then call this method.

In some circumstances, it is possible that both renderResponse() and responseComplete() might have been called for the request. [P1-start-flowControl]In this case, the Jakarta Faces implementation must respect the responseComplete() call (if it was made) before checking to see if renderResponse() was called.[P1-end]

The getRenderResponse() and getResponseComplete() methods allow a Jakarta Faces-based application to determine whether the renderResponse() or responseComplete() methods, respectively, have been called already for the current request.

6.1.10. Partial Processing Methods

public PartialViewContext getPartialViewContext();

[P1-start-getpartialViewContext]The getPartialViewContext()method must return an instance of PartialViewContext either by creating a new instance, or returning an existing instance from the FacesContext.[P1-end-getpartialViewcontext]

6.1.11. Partial View Context

The PartialViewContext contains the constants, properties and methods to facilitate partial view processing and partial view rendering. Refer to Partial View Processing and Partial View Rendering. Refer to the JavaDocs for the jakarta.faces.context.PartialViewContext class for method requirements.

6.1.12. Access To The Current FacesContext Instance

public static FacesContext getCurrentInstance();
protected static void setCurrentInstance(FacesContext context);

Under most circumstances, Jakarta Faces components, and application objects that access them, are passed a reference to the FacesContext instance for the current request. However, in some cases, no such reference is available. The getCurrentInstance() method may be called by any Java class in the current web application to retrieve an instance of the FacesContext for this request. [P1-start-currentInstance]The Jakarta Faces implementation must ensure that this value is set correctly before FacesContextFactory returns a FacesContext instance, and that the value is maintained in a thread-safe manner.[P1-end]

[P1-start facesContextDuringInit] The default implementation must allow this method to be called during application startup time, before any requests have been serviced. If called during application startup time, the instance returned must have the special properties as specified on the javadocs for FacesContext.getCurrentInstance() The . [P1-end]

6.1.13. CurrentPhaseId

The default lifecycle implementation is responsible for setting the currentPhaseId property on the FacesContext instance for this request, as specified in Standard Request Processing Lifecycle Phases. The following table describes this property.

Name Access Type Description

currentPhaseId

RW

PhaseId

The PhaseId constant for the current phase of the request processing lifecycle

6.1.14. ExceptionHandler

The FacesContextFactory ensures that each newly created FacesContext instance is initialized with a fresh instance of ExceptionHandler, created from ExceptionHandlerFactory. The following table describes this property.

Name Access Type Description

exceptionHandler

RW

ExceptionHandler

Set by FacesContextFactory.getFacesContext(), this class is the default exception handler for any unexpected Exceptions that happen during the Faces lifecycle. See the Javadocs for ExceptionHandler for details.

Please see PhaseListener for the circumstances under which ExceptionHandler is used.

6.2. ExceptionHandler

ExceptionHandler is the central point for handling unexpected Exceptions that are thrown during the Faces lifecycle. The ExceptionHandler must not be notified of any Exceptions that occur during application startup or shutdown.

Several places in the Faces specification require an Exception to be thrown as a result of normal lifecycle processing. [P1-start_expected_exceptions]The following expected Exception cases must not be handled by the ExceptionHandler.

  • All cases where a ValidatorException is specified to be thrown or caught

  • All cases where a ConverterException is specified to be thrown or caught

  • The case when a MissingResourceException is thrown during the processing of the <f:loadBundle /> tag.

  • If an exception is thrown when the runtime is processing the @PreDestroy annotation on a managed bean.

  • All classes when an AbortProcessingException is thrown.

All other Exception cases must not be swallowed, and must be allowed to flow up to the Lifecycle.execute() method where the individual lifecycle phases are implemented. [P1-end_expected_exceptions] At that point, all Exceptions are passed to the ExceptionHandler as described in PhaseListener.

Any code that is not a part of the core Faces implementation may leverage the ExceptionHandler in one of two ways.

6.2.1. Default ExceptionHandler implementation

The default ExceptionHandler must implement the following behavior for each of its methods

public ExceptionQueuedEvent getHandledExceptionEvent();

Return the first “handled” ExceptionQueuedEvent, that is, the one that was actually re-thrown.

public Iterable<ExceptionQueuedEvent> getHandledExceptionEvents();

The default implementation must return an Iterable over all ExceptionEvents that have been handled by the handle() method.

public Throwable getRootCause(Throwable t);

Unwrap the argument t until the unwrapping encounters an Object whose getClass() is not equal to FacesException.class or jakarta.el.ELException.class. If there is no root cause, null is returned.

public Iterable<ExceptionQueuedEvent> getUnhandledExceptionEvents();

Return an Iterable over all ExceptionEvents that have not yet been handled by the handle() method.

public void handle() throws FacesException;

Inspect all unhandled ExceptionQueuedEvent instances in the order in which they were queued by calls to Application.publishEvent(ExceptionQueuedEvent.class, eventContext).

For each ExceptionQueuedEvent in the list, call its getContext() method and call getException() on the returned result. Upon encountering the first such Exception the corresponding ExceptionQueuedEvent must be set so that a subsequent call to getHandledExceptionEvent() or getHandledExceptionEvents() returns that ExceptionQueuedEvent instance. The implementation must also ensure that subsequent calls to getUnhandledExceptionEvents() do not include that ExceptionQueuedEvent instance. Let toRethrow be either the result of calling getRootCause() on the Exception, or the Exception itself, whichever is non-null. Re-wrap toThrow in a ServletException or (PortletException, if in a portlet environment) and throw it, allowing it to be handled by any <error-page> declared in the web application deployment descriptor or by the default error page as described elsewhere in this section.

There are two exceptions to the above processing rules. In both cases, the Exception must be logged and not re-thrown.

  • If an unchecked Exception occurs as a result of calling a method annotated with PreDestroy on a managed bean.

  • If the Exception originates inside the ELContextListener.removeElContextListener() method

The FacesException must be thrown if and only if a problem occurs while performing the algorithm to handle the Exception, not as a means of conveying a handled Exception itself.

public boolean isListenerForSource(Object source);

The default implementation must return true if and only if the source argument is an instance of ExceptionEventContext.

public void processEvent(SystemEvent ExceptionQueuedEvent)
    throws AbortProcessingException;

The default implementation must store the argument ExceptionQueuedEvent in a strongly ordered queue for later processing by the handle() method.

6.2.2. Backwards Compatible ExceptionHandler

[P1-startPreJsf2ExceptionHandler]The runtime must provide an ExceptionHandlerFactory implementation with the fully qualified java classname of jakarta.faces.webapp.PreJsf2ExceptionHandlerFactory that creates ExceptionHandler instances that behave exactly like the default ExceptionHandler except that the handle() method behaves as follows.

  • Pre-Jakarta Faces JSF 1.1 and 1.2 (under the JCP) stated in PhaseListener “Any exceptions thrown during the beforePhase() listeners must be caught, logged, and swallowed…​Any exceptions thrown during the afterPhase() liseteners must be caught, logged, and swallowed.” The PreJsf2ExceptionHandler restores this behavior for backwards compatibilty.

The implementation must allow users to install this ExceptionHandlerFactory into the application by nesting <exception-handler-factory>jakarta.faces.webapp.PreJsf2ExceptionHandlerFactory</exception-handler-factory> inside the <factory> element in the application configuration resource.[P1-endPreJsf2ExceptionHandler]

6.2.3. Default Error Page

If no <error-page> elements are declared in the web application deployment descriptor, the runtime must provide a default error page that contains the following information.

  • The stack trace of the Exception

  • The UIComponent tree at the time the ExceptionQueuedEvent was handled.

  • All scoped variables in request, view, session and application scope.

  • If the error happens during the execution of the view declaration language page (VDL)

    • The physical file being traversed at the time the Exception was thrown, such as /user.xhtml

    • The line number within that physical file at the time the Exception was thrown

    • Any available error message(s) from the VDL page, such as: “The prefix "foz" for element "foz:bear" is not bound.”

  • The viewId at the time the ExceptionQueuedEvent was handled

If Application.getProjectStage() returns ProjectStage.Development, the runtime must guarantee that the above debug information is available to be included in any Facelet based error page using the <ui:include /> with a src attribute equal to the string “jakarta.faces.error.xhtml”.

6.3. FacesMessage

Each message queued within a FacesContext is an instance of the jakarta.faces.application.FacesMessage class. The presence of one or more FacesMessage instances on the FacesContext indicates a failure of some kind during the lifecycle. In particular, a validation or conversion failure is required to cause a FacesMessage to be added to the FacesContext.

It offers the following constructors:

public FacesMessage();
public FacesMessage(String summary, String detail);
public FacesMessage(Severity severity, String summary, String detail);

The following method signatures are supported to retrieve and set the properties of the completed message:

public String getDetail();
public void setDetail(String detail);

public Severity getSeverity();
public void setSeverity(Severity severity);

public String getSummary();
public void setSummary(String summary);

The message properties are defined as follows:

  • detail —Localized detail text for this FacesMessage (if any). This will generally be additional text that can help the user understand the context of the problem being reported by this FacesMessage, and offer suggestions for correcting it.

  • severity —A value defining how serious the problem being reported by this FacesMessage instance should be considered. Four standard severity values (SEVERITY_INFO, SEVERITY_WARN, SEVERITY_ERROR, and SEVERITY_FATAL) are defined as a typesafe enum in the FacesMessage class.

  • summary —Localized summary text for this FacesMessage. This is normally a relatively short message that concisely describes the nature of the problem being reported by this FacesMessage.

6.4. ResponseStream

ResponseStream is an abstract class representing a binary output stream for the current response. It has exactly the same method signatures as the java.io.OutputStream class.

6.5. ResponseWriter

ResponseWriter is an abstract class representing a character output stream for the current response. A ResponseWriter instance is obtained via a factory method on RenderKit. Please see RenderKit. It supports both low-level and high level APIs for writing character based information

public void close() throws IOException;
public void flush() throws IOException;
public void write(char c[]) throws IOException;
public void write(char c[], int off, int len) throws IOException;
public void write(int c) throws IOException;
public void write(String s) throws IOException;
public void write(String s, int off, int len) throws IOException;

The ResponseWriter class extends java.io.Writer, and therefore inherits these method signatures for low-level output. The close() method flushes the underlying output writer, and causes any further attempts to output characters to throw an IOException. The flush method flushes any buffered information to the underlying output writer, and commits the response. The write methods write raw characters directly to the output writer.

public abstract String getContentType();
public abstract String getCharacterEncoding();

Return the content type or character encoding used to create this ResponseWriter.

public void startCDATA();
public void endCDATA();

Start and end an XML CDATA Section..

public void startDocument() throws IOException;
public void endDocument() throws IOException;

Write appropriate characters at the beginning (startDocument) or end (endDocument) of the current response.

public void startElement(String name,
    UIComponent componentForElement) throws IOException;

Write the beginning of a markup element (the < character followed by the element name), which causes the ResponseWriter implementation to note internally that the element is open. This can be followed by zero or more calls to writeAttribute or writeURIAttribute to append an attribute name and value to the currently open element. The element will be closed (i.e. the trailing > added) on any subsequent call to startElement(), writeComment(), writeText(), endDocument(), close(), flush(), or write(). The componentForElement parameter tells the ResponseWriter which UIComponent this element corresponds to, if any. This parameter may be null to indicate that the element has no corresponding component. The presence of this parameter allows tools to provide their own implementation of ResponseWriter to allow the design time environment to know which component corresponds to which piece of markup.

public void endElement(String name) throws IOException;

Write a closing for the specified element, closing any currently opened element first if necessary.

public void writeComment(Object comment) throws IOException;

Write a comment string wrapped in appropriate comment delimiters, after converting the comment object to a String first. Any currently opened element is closed first.

public void writeAttribute(String name, Object value,
    String componentPropertyName) throws IOException;

public void writeURIAttribute(String name, Object value,
    String componentPropertyName) throws IOException;

These methods add an attribute name/value pair to an element that was opened with a previous call to startElement(), throwing an exception if there is no currently open element. The writeAttribute() method causes character encoding to be performed in the same manner as that performed by the writeText() methods. The writeURIAttribute() method assumes that the attribute value is a URI, and performs URI encoding (such as % encoding for HTML). The componentPropertyName, if present, denotes the property on the associated UIComponent for this element, to which this attribute corresponds. The componentPropertyName parameter may be null to indicate that this attribute has no corresponding property.

public void writeText(Object text, String property) throws IOException;
public void writeText(char text[], int off, int len) throws IOException;

Write text (converting from Object to String first, if necessary), performing appropriate character encoding and escaping. Any currently open element created by a call to startElement is closed first.

public abstract ResponseWriter cloneWithWriter(Writer writer);

Creates a new instance of this ResponseWriter, using a different Writer.

6.6. FacesContextFactory

[P1-start-facesContextFactory]A single instance of jakarta.faces.context.FacesContextFactory must be made available to each Jakarta Faces-based web application running in a servlet or portlet container.[P1-end] This class is primarily of use by Jakarta Faces implementors—applications will not generally call it directly. The factory instance can be acquired, by Jakarta Faces implementations or by application code, by executing:

FacesContextFactory factory = (FacesContextFactory)
    FactoryFinder.getFactory(FactoryFinder.FACES_CONTEXT_FACTORY);

The FacesContextFactory implementation class provides the following method signature to create (or recycle from a pool) a FacesContext instance:

public FacesContext getFacesContext(Object context,
    Object request, Object response, Lifecycle lifecycle);

Create (if necessary) and return a FacesContext instance that has been configured based on the specified parameters. In a servlet environment, the first argument is a ServletContext, the second a ServletRequest and the third a ServletResponse.

6.7. ExceptionHandlerFactory

[P1-start-exceptionHandlerFactory]A single instance of jakarta.faces.context.ExceptionHandlerFactory must be made available to each Jakarta Faces-based web application running in a servlet or portlet container.[P1-end] The factory instance can be acquired, by Jakarta Faces implementations or by application code, by executing:

ExceptionHandlerFactory factory = (ExceptionHandlerFactory)
    FactoryFinder.getFactory(FactoryFinder.EXCEPTION_HANDLER_FACTORY);

The ExceptionHandlerFactory implementation class provides the following method signature to create an ExceptionHandler instance:

public ExceptionHandler getExceptionHandler(FacesContext currentContext);

Create and return a ExceptionHandler instance that has been configured based on the specified parameters.

6.8. ExternalContextFactory

[P1-start-externalContextFactory]A single instance of jakarta.faces.context.ExternalContextFactory must be made available to each Jakarta Faces-based web application running in a servlet or portlet container.[P1-end] This class is primarily of use by Jakarta Faces implementors—applications will not generally call it directly. The factory instance can be acquired, by Jakarta Faces implementations or by application code, by executing:

ExternalContextFactory factory = (ExternalContextFactory)
    FactoryFinder.getFactory(FactoryFinder.EXTERNAL_CONTEXT_FACTORY);

The ExternalContextFactory implementation class provides the following method signature to create (or recycle from a pool) a FacesContext instance:

public ExternalContext getExternalContext(
Object context, Object request, Object response);

Create (if necessary) and return an ExternalContext instance that has been configured based on the specified parameters. In a servlet environment, the first argument is a ServletContext, the second a ServletRequest and the third a ServletResponse.

7. Application Integration

Previous chapters of this specification have described the component model, request state information, and the next chapter describes the rendering model for Jakarta Server Faces user interface components. This chapter describes APIs that are used to link an application’s business logic objects, as well as convenient pluggable mechanisms to manage the execution of an application that is based on Jakarta Server Faces. These classes are in the jakarta.faces.application package.

Access to application related information is centralized in an instance of the Application class, of which there is a single instance per application based on Jakarta Server Faces. Applications will typically provide one or more implementations of ActionListener (or a method that can be referenced by an action expression) in order to respond to ActionEvent events during the Apply Request Values or Invoke Application phases of the request processing lifecycle. Finally, a standard implementation of NavigationHandler (replaceable by the application or framework) is provided to manage the selection of the next view to be rendered.

7.1. Application

There must be a single instance of Application per web application that is utilizing Jakarta Server Faces. It can be acquired by calling the getApplication() method on the FacesContext instance for the current request, or the getApplication() method of the ApplicationFactory (see ApplicationFactory), and provides default implementations of features that determine how application logic interacts with the Jakarta Faces implementation. Advanced applications (or application frameworks) can install replacements for these default implementations, which will be used from that point on. Access to several integration objects is available via JavaBeans property getters and setters, as described in the following subsections.

7.1.1. ActionListener Property

public ActionListener getActionListener();
public void setActionListener(ActionListener listener);

Return or replace an ActionListener instance that will be utilized to process ActionEvent events during the Apply Request Values or Invoke Application phase of the request processing lifecycle. [P1-start default ActionListener requirements] The Jakarta Faces implementation must provide a default implementation ActionListener that performs the following functions:

  • The processAction() method must first call FacesContext.renderResponse() in order to bypass any intervening lifecycle phases, once the method returns.

  • The processAction() method must next determine the logical outcome of this event, as follows:

    • If the originating component has a non-null action property, retrieve the MethodBinding and call invoke() to perform the application-specified processing in this action method. If the method returns non- null, call toString() on the result and use the value returned as the logical outcome. See Properties for a decription of the action property.

    • Otherwise, the logical outcome is null.

  • The processAction() method must finally retrieve the NavigationHandler instance for this application, and pass the logical outcome value (determined above) as a parameter to the handleNavigation() method of the NavigationHandler instance. If the originating component has an attribute whose name is equal to the value of the symbolic constant ActionListener.TO_FLOW_DOCUMENT_ID_ATTR_NAME, invoke handleNavigation(FacesContext, String, String, String) passing the value of the attribute as the last parameter. Otherwise, invoke handleNavigation(FacesContext, String, String). In either case, the first String argument is the expression string of the fromAction and the second String argument is the logical outcome.[P1-end]

See the Javadocs for getActionListener() for important backwards compatability information.

7.1.2. DefaultRenderKitId Property

public String getDefaultRenderKitId();
public void setDefaultRenderKitId(String defaultRenderKitId);

An application may specify the render kit identifier of the RenderKit to be used by the ViewHandler to render views for this application. If not specified, the default render kit identifier specified by RenderKitFactory.HTML_BASIC_RENDER_KIT will be used by the default ViewHandler implementation.

[P1-start defaultRenderKit called after startup] Unless the application has provided a custom ViewHandler that supports the use of multiple RenderKit instances in the same application, this method may only be called at application startup, before any Faces requests have been processed. [P1-end] This is a limitation of the current Specification, and may be lifted in a future release.

7.1.3. FlowHandler Property

public FlowHandler getFlowHandler();
public void setFlowHandler(FlowHandler handler);

Return or replace the FlowHandler that will be used by the NavigationHandler to make decisions about navigating application flow. See FlowHandler for an overview of the flow feature.

[P1-start flowHandler called after startup] setFlowHandler() may only be called at application startup, before any Faces requests have been processed. [P1-end] This is a limitation of the current Specification, and may be lifted in a future release. getFlowHandler() may be called at any time after application startup.

public NavigationHandler getNavigationHandler();
public void setNavigationHandler(NavigationHandler handler);

Return or replace the NavigationHandler instance (see NavigationHandler) that will be passed the logical outcome of the application ActionListener as described in the previous subsection. A default implementation must be provided, with functionality described in Default NavigationHandler Algorithm:

7.1.5. StateManager Property

public StateManager getStateManager();
public void setStateManager(StateManager manager);

Return or replace the StateManager instance that will be utilized during the Restore View and Render Response phases of the request processing lifecycle to manage state persistence for the components belonging to the current view. A default implementation must be provided, which operates as described in StateManager.

7.1.6. ELResolver Property

public ELResolver getELResolver();
public void addELResolver(ELResolver resolver);

[N/T-start elresolver test] Return the ELResolver instance to be used for all Expression Language resolution. This is actually an instance of jakarta.el.CompositeELResolver that must contain the ELResolver instances as specified in ELResolver for Facelets and Programmatic Access. [N/T-end]

[N/T-start addELResolver ordering] addELResolver must cause the argument resolver to be added at the end of the list in the jakarta.el.CompositeELResolver returned from getELResolver(). See the diagram in ELResolver for Facelets and Programmatic Access [N/T-end]

7.1.7. ELContextListener Property

public addELContextListener(ELContextListener listener);
public void removeELContextListener(ELContextListener listener);
public ELContextListener[] getELContextListeners();

addELContextListener() registers an ELContextListener for the current Faces application. This listener will be notified on creation of ELContext instances, and it will be called once per request.

removeELContextListener() removes the argument listener from the list of ELContextListeners. If listener is null, no exception is thrown and no action is performed. If listener is not in the list, no exception is thrown and no action is performed.

getELContextListeners() returns an array representing the list of listeners added by calls to addELContextListener().

7.1.8. ViewHandler Property

public ViewHandler getViewHandler();
public void setViewHandler(ViewHandler handler);

See ViewHandler for the description of the ViewHandler. The Jakarta Faces implementation must provide a default ViewHandler implementation. This implementation may be replaced by calling setViewHandler() before the first time the Render Response phase has executed. [P1-start setViewHandler() called after startup] If a call is made to setViewHandler() after the first time the Render Response phase has executed, the call must be ignored by the implementation. [P1-end]

7.1.9. ProjectStage Property

public ProjectStage getProjectStage();

[P1-start getProjectStage]This method must return the enum constant from the class jakarta.faces.application.ProjectStage as specified in the corresponding application init parameter, JNDI entry, or default Value. See Application Configuration Parameters.[P1-end]

7.1.10. Acquiring ExpressionFactory Instance

public ExpressionFactory getExpressionFactory();

Return the ExpressionFactory instance for this application. This instance is used by the evaluateExpressionGet (See Programmatically Evaluating Expressions) convenience method.

[P1-start getExpressionFactory requirements] The default implementation simply returns the ExpressionFactory from the Jakarta Server Pages container by calling JspFactory.getDefaultFactory().getJspApplicationContext(servletContext).getExpressionFactory().[P1-end]

7.1.11. Programmatically Evaluating Expressions

public Object evaluateExpressionGet(FacesContext context,
    String expression, Class expectedType)

Get a value by evaluating an expression.

Call getExpressionFactory().createValueExpression() passing the argument expression and expectedType. Call FacesContext.getELContext() and pass it to ValueExpression.getValue(), returning the result.

It is also possible and sometimes desireable to obtain the actual ValueExpression or MethodExpression instance directly. This can be accomplished by using the createValueExpression() or createMethodExpression() methods on the ExpressionFactory returned from getExpressionFactory().

7.1.12. Object Factories

The Application instance for a web application also acts as an object factory for the creation of new Jakarta Faces objects such as components, converters, validators and behaviors..

public UIComponent createComponent(String componentType);
public UIComponent createComponent(
    String componentType, String rendererType);

public Converter createConverter(Class targetClass);
public Converter createConverter(String converterId);
public Validator createValidator(String validatorId);
public Behavior createBehavior(String behaviorId);

Each of these methods creates a new instance of an object of the requested type 6, based on the requested identifier. The names of the implementation class used for each identifier is normally provided by the Jakarta Faces implementation automatically (for standard classes described in this Specification), or in one or more application configuration resources (see Application Configuration Resources) included with a Jakarta Faces web application, or embedded in a JAR file containing the corresponding implementation classes.

All variants createConverter() must take some action to inspect the converter for @ResourceDependency and @ListenerFor annotations.

public UIComponent createComponent(ValueExpression componentExpression,
    FacesContext context, String componentType);

[P1-start createComponent(ValueExpression) requirements] This method has the following behavior:

  • Call the getValue() method on the specified ValueExpression, in the context of the specified FacesContext. If this results in a non-null UIComponent instance, return it as the value of this method.

  • If the getValue() call did not return a component instance, create a new component instance of the specified component type, pass the new component to the s etValue() method of the specified ValueExpression, and return it.[P1-end]

public UIComponent createComponent(
    FacesContext context, Resource componentResource);

All variants createComponent() must take some action to inspect the component for @ResourceDependency and @ListenerFor annotations. Please see the JavaDocs and Composite Component Metadata for the normative specification relating to this method.

public void addComponent(String componentType, String componentClass);
public void addConverter(Class targetClass, String converterClass);
public void addConverter(String converterId, String converterClass);
public void addValidator(String validatorId, String validatorClass);
public void addBehavior(String behaviorId, String behaviorClass);

Jakarta Faces-based applications can register additional mappings of identifiers to a corresponding fully qualified class name, or replace mappings provided by the Jakarta Faces implementation in order to customize the behavior of standard Jakarta Faces features. These methods are also used by the Jakarta Faces implementation to register mappings based on <component>, <converter>, <behavior> and <validator> elements discovered in an application configuration resource.

public Iterator<String> getComponentTypes();
public Iterator<String> getConverterIds();
public Iterator<Class> getConverterTypes();
public Iterator<String> getValidatorIds();
public Iterator<String> getBehaviorIds();

Jakarta Faces-based applications can ask the Application instance for a list of the registered identifiers for components, converters, and validators that are known to the instance.

7.1.12.1. Default Validator Ids

From the list of mappings of validatorId to fully qualified class name, added to the application via calls to addValidator(), the application maintains a subset of that list under the heading of default validator ids. The following methods provide access to the default validator ids registered on an application:

public void addDefaultValidatorId(String validatorId);
public Map<String,String> getDefaultValidatorInfo();

The required callsites for these methods are specified in Validation Registration.

7.1.13. Internationalization Support

The following methods and properties allow an application to describe its supported locales, and to provide replacement text for standard messages created by Jakarta Faces objects.

public Iterator<Locale> getSupportedLocales();
public void setSupportedLocales(Collection<Locale> newLocales);
public Locale getDefaultLocale();
public void setDefaultLocale(Locale newLocale);

Jakarta Faces applications may state the Locale s they support (and the default Locale within the set of supported Locales) in the application configuration resources file. The setters for the following methods must be called when the configuration resources are parsed. Each time the setter is called, the previous value is overwritten.

public String getMessageBundle();
public void setMessageBundle(String messageBundle);

Specify the fully qualified name of the ResourceBundle from which the Jakarta Faces implementation will acquire message strings that correspond to standard message keys See Localized Application Messages for a list of the standard message keys recognized by Jakarta Faces.

7.1.14. System Event Methods

System events are described in System Events. This section describes the methods defined on Application that support system events

7.1.14.1. Subscribing to system events
public abstract void subscribeToEvent(Class<? extends SystemEvent>
    systemEventClass, SystemEventListener listener)

public abstract void subscribeToEvent(Class<? extends SystemEvent>
    systemEventClass, Class sourceClass, SystemEventListener listener);

public abstract void publishEvent(Class<? extends SystemEvent>
    systemEventClass, SystemEventListenerHolder source);

public void publishEvent(Class<? extends SystemEvent>
    systemEventClass, Class<?> sourceBaseType, Object source)

The first variant of subscribeToEvent() subscribes argument listener to have its isListenerForSource() method, and (depending on the result from isListenerForSource()) its processEvent() method called any time any call is made to Application.publishEvent(Class<? extends SystemEvent> systemEventClass, SystemEventListenerHolder source) where the first argument in the call to publishEvent() is equal to the first argument to subscribeToEvent(). [P1-start eventClassAndInheritance] NOTE : The implementation must not support subclasses for the systemEventClass and/or sourceClass arguments to subscribeToEvent() or publishEvent().[P1-end] For example, consider two event types, SuperEvent and SubEvent extends SuperEvent. If a listener subscribes to SuperEvent.class events, but later someone publishes a SubEvent.class event (which extends SuperEvent), the listener for SuperEvent.class must not be called.

The second variant of subscribeToEvent() is equivalent to the first, with the additional constraint the the sourceClass argument to publishEvent() must be equal to the Class object obtained by calling getClass() on the source argument to publishEvent().

See the javadocs for both variants of subscribeForEvent() for the complete specification of these methods.

publishEvent() is called by the system at several points in time during the runtime of a Jakarta Faces application. The specification for when publishEvent() is called is given in the javadoc for the event classes that are listed in Event Classes. See the javadoc for publishEvent() for the complete specification.

7.1.14.2. Unsubscribing from system events
public abstract void unsubscribeFromEvent(Class<? extends SystemEvent>
    systemEventClass, SystemEventListener listener);

public abstract void unsubscribeFromEvent(Class<? extends SystemEvent>
    systemEventClass, Class sourceClass, SystemEventListener listener);

See the javadocs for both variants of unsubscribeFromEvent() for the complete specification.

7.2. ApplicationFactory

A single instance of jakarta.faces.application.ApplicationFactory must be made available to each Jakarta Faces-based web application running in a servlet or portlet container. The factory instance can be acquired by Jakarta Faces implementations or by application code, by executing:

ApplicationFactory factory = (ApplicationFactory)
    FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);

The ApplicationFactory implementation class supports the following methods:

public Application getApplication();
public void setApplication(Application application);

Return or replace the Application instance for the current web application. The Jakarta Faces implementation must provide a default Application instance whose behavior is described in Application.

Note that applications will generally find it more convenient to access the Application instance for this application by calling the getApplication() method on the FacesContext instance for the current request.

7.3. Application Actions

An application action is an application-provided method on some Java class that performs some application-specified processing when an ActionEvent occurs, during either the Apply Request Values or the Invoke Application phase of the request processing lifecycle (depending upon the immediate property of the ActionSource instance initiating the event).

Application action is not a formal Jakarta Faces API; instead any method that meets the following requirements may be used as an Action by virtue of evaluating a method binding expression:

  • The method must be public.

  • The method must take no parameters.

  • The method must return Object.

The action method will be called by the default ActionListener implementation, as described in ActionListener Property above. Its responsibility is to perform the desired application actions, and then return a logical “outcome” (represented as a String) that can be used by a NavigationHandler in order to determine which view should be rendered next. The action method to be invoked is defined by a MethodBinding that is specified in the action property of a component that implements ActionSource. Thus, a component tree with more than one such ActionSource component can specify individual action methods to be invoked for each activated component, either in the same Java class or in different Java classes.

7.4. NavigationHandler

7.4.1. Overview

Most Jakarta Faces applications can be thought of as a directed graph of views, each node of which roughly corresponds to the user’s perception of “location” within the application. Applications that use the Faces Flows feature have additional kinds of nodes in the directed graph. In any case, navigating the nodes of this graph is the responsibility of the NavigationHandler. A single NavigationHandler instance is responsible for consuming the logical outcome returned by an application action that was invoked, along with additional state information that is available from the FacesContext instance for the current request, and (optionally) selecting a new view to be rendered. If the outcome returned by the applicationaction is null or the empty string, and none of the navigation cases that map to the current view identifier have a non-null condition expression, the same view must be re-displayed. This is a change from the old behavior. As of pre-Jakarta Faces JSF 2.0 (under the JCP), the NavigationHandler is consulted even on a null outcome, but under this circumstance it only checks navigation cases that do not specify an outcome (no <from-outcome>) and have a condition expression (specified with <if>). This is the only case where the same view (and component tree) is re-used.

public void handleNavigation(FacesContext context,
    String fromAction, String outcome);

The handleNavigation method may select a new view by calling createView() on the ViewHandler instance for this application, optionally customizing the created view, and then selecting it by calling the setViewRoot() method on the FacesContext instance that is passed. Alternatively, the NavigationHandler can complete the actual response (for example, by issuing an HTTP redirect), and call responseComplete() on the FacesContext instance.

After a return from the handleNavigation method, control will normally proceed to the Render Response phase of the request processing lifecycle (see Render Response), which will cause the newly selected view to be rendered. If the NavigationHandler called the responseComplete() method on the FacesContext instance, however, the Render Response phase will be bypassed.

Jakarta Faces also contains the ConfigurableNavigationHandler interface, which extends the contract of the NavigationHandler to include two additional methods that accommodate runtime inspection of the NavigationCases that represent the rule-based navigation metamodel. The method getNavigationCase consults the NavigationHandler to determine which NavigationCase the handleNavigation method would resolve for a given "from action" expression and logical outcome combination. The method getNavigationCases returns a java.util.Map of all the NavigationCase instances known to this NavigationHandler. Each key in the map is a from view ID and the cooresponding value is a java.util.Set of NavigationCases for that from view ID.

public NavigationCase getNavigationCase(FacesContext context,
    String fromAction, String outcome);

public Map<String, Set<NavigationCase>> getNavigationCases();

[P1-start-configurablenavhandler]A Jakarta Faces compliant-implemention must ensure that its NavigationHandler implements the ConfigurableNavigationHandler interface. The handleNavigation and getNavigation Case methods should use the same logic to resolve a NavigationCase, which is outlined in the next section.[P1-end]

7.4.2. Default NavigationHandler Algorithm

Jakarta Faces implementations must provide a default NavigationHandler implementation that maps the action reference that was utilized (by the default ActionListener implementation) to invoke an application action, the logical outcome value returned by that application action, as well as other state information, into the view identifier for the new view or flow node to be selected. The remainder of this section describes the functionality provided by this default implementation.

The behavior of the default NavigationHandler implementation is configured, at web application startup time, from the contents of zero or more application configuration resources (see Application Configuration Resources). The configuration information is represented as zero or more <navigation-rule> elements, each keyed to a matching pattern for the view identifier of the current view expressed in a <from-view-id> element. This matching pattern must be either an exact match for a view identifier (such as “/index.jsp” if you are using the default ViewHandler), or the prefix of a component view id, followed by an asterisk (“*”) character. A matching pattern of “*”, or the lack of a <from-view-id> element inside a <navigation-rule> rule, indicates that this rule matches any possible component view identifier.

Version 2.2 of the specification introduced the Faces Flows feature. [P1-start-FlowNavigationConstraints] With respect to the navigation algorithm, any text that references a view identifier, such as <from-view-id> or <to-view-id>, can also refer to a flow node, subject to these constraints.

  • When outside of a flow, view identifier has the additional possibility of being a flow id.

  • When inside a flow, a view identifier has the additional possibility of being the id of any node within the current flow.[P1-end]

If the specification needs to refer to a view identifier that is an actual VDL view (and not a VDL view or a flow, or flow node), the term vdl view identifier will be used.

Nested within each <navigation-rule> element are zero or more <navigation-case> elements that contain additional matching criteria based on the action reference expression value used to select an application action to be invoked (if any), and the logical outcome returned by calling the invoke() method of that application action 7. Navigation cases support a condition element, <if>, whose content must be a single, contiguous value expression expected to resolve to a boolean value (if the content does not match this requirement, the condition is ignored) 8. When the <if> element is present, the value expression it contains must evaluate to true when the navigation case is being consulted in order for the navigation case to match 9. Finally, the <navigation-case> element contains a <to-view-id> element, whose content is either the view identifier or a value expression that resolves to the view identifier. If the navigation case is a match, this view identifier is to be selected and stored in the FacesContext for the current request following the invocation of the NavigationHandler. See below for an example of the configuration information for the default NavigationHandler might be configured.

It is permissible for the application configuration resource(s) used to configure the default NavigationHandler to include more than one <navigation-rule> element with the same <from-view-id> matching pattern. For the purposes of the algorithm described below, all of the nested <navigation-case> elements for all of these rules shall be treated as if they had been nested inside a single <navigation-rule> element.

[P1-start navigation handler requirements] The default NavigationHandler implementation must behave as if it were performing the following algorithm (although optimized implementation techniques may be utilized):

  • If no navigation case is matched by a call to the handleNavigation() method, this is an indication that the current view should be redisplayed. A null outcome does not unconditionally cause all navigation rules to be skipped.

  • Find a <navigation-rule> element for which the view identifier (of the view in the FacesContext instance for the current request) matches the <from-view-id> matching pattern of the <navigation-rule>. Rule instances are considered in the following order:

    • An exact match of the view identifier against a <from-view-id> pattern that does not end with an asterisk (“*”) character.

    • For <from-view-id> patterns that end with an asterisk, an exact match on characters preceding the asterisk against the prefix of the view id. If the patterns for multiple navigation rules match, pick the longest matching prefix first.

    • If there is a <navigation-rule> with a <from-view-id> pattern of only an asterisk 10, it matches any view identifier.

  • From the <navigation-case> elements nested within the matching <navigation-rule> element, locate a matching navigation case by matching the <from-action> and <from-outcome> values against the fromAction and outcome parameter values passed to the handleNavigation() method. To match an outcome value of null, the <from-outcome> must be absent and the <if> element present. Regardless of outcome value, if the <if> element is present, evaluate the content of this element as a value expression and only select the navigation case if the expression resolves to true. Navigation cases are checked in the following order:

    • Cases specifying both a <from-action> value and a <from-outcome> value are matched against the action expression and outcome parameters passed to the handleNavigation() method (both parameters must be not null, and both must be equal to the corresponding condition values, in order to match).

    • Cases that specify only a <from-outcome> value are matched against the outcome parameter passed to the handleNavigation() method (which must be not null, and equal to the corresponding condition value, to match).

    • Cases that specify only a <from-action> value are matched against the action expression parameter passed to the handleNavigation() method (which must be non-null, and equal to the corresponding condition value, to match; if the <if> element is absent, only match a non-null outcome; otherwise, match any outcome).

    • Any remaining case is assumed to match so long as the outcome parameter is non-null or the <if> element is present.

    • For cases that match up to this point and contain an <if> element, the condition value expression must be evaluated and the resolved value true for the case to match.

  • If a matching <navigation-case> element was located, proceed as follows.

    • If the <to-view-id> element is the id of a flow, discover that flow’s start node and resolve it to a vdl view identifier by following the algorithm in Requirements for Explicit Navigation in Faces Flow Call Nodes other than ViewNodes

    • If the <to-view-id> element is a non-view flow node, resolve it to a vdl view identifier by following the algorithm in Requirements for Explicit Navigation in Faces Flow Call Nodes other than ViewNodes.

    • If UIViewAction.isProcessingBroadcast() returns true, call getFlash().setKeepMessages(true) on the current FacesContext. Compare the viewId of the current viewRoot with the <to-view-id> of the matching <navigation-case>. If they differ, take any necessary actions to effectively restart the Jakarta Faces lifecycle on the <to-view-id> of the matching <navigation-case>. Care must be taken to preserve any view parameters or navigation case parameters, clear the view map of the UIViewRoot, and call setRenderAll(true) on the PartialViewContext. Implementations may choose to meet this requirement by treating this case as if a <redirect /> was specified on the matching <navigation-case>. If the viewIds do not differ, continue on to the next bullet point.

    • Clear the view map if the viewId of the new UIViewRoot differs from the viewId of the current UIViewRoot.

    • If the <redirect/> element was not specified in this <navigation-case> (or the application is running in a Portlet environment, where redirects are not possible), use the <to-view-id> element of the matching case to request a new UIViewRoot instance from the ViewHandler instance for this application. Call transition() on the FlowHandler, passing the current FacesContext, the current flow, the new flow and the facesFlowCallNode corresponding to this faces flow call, if any. Pass the new UIViewRoot to the setViewRoot() method of the FacesContext instance for the current request.

      Then, exit the algorithm. If the content of <to-view-id> is a value expression, first evaluate it to obtain the value of the view id.

    • If the <redirect/> element was specified in this <navigation-case>, or this invocation of handleNavigation() was due to a UIViewAction broadcast event where the new viewId is different from the current viewId, resolve the <to-view-id> to a view identifier, using the algorithm in Requirements for Explicit Navigation in Faces Flow Call Nodes other than ViewNodes. Call getRedirectURL() on the ViewHandler, passing the current FacesContext, the <to-view-id>, any name=value parameter pairs specified within <view-param> elements within the <redirect> element, and the value of the include-view-params attribute of the <redirect /> element if present, false, if not. If this navigation is a flow transition (where current flow is not the same as the new flow), include the relevant flow metadata as entries in the parameters .

      • If current flow is not null and new flow is null, include the following entries: FlowHandler.TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME: FlowHandler.NULL_FLOW
        FlowHandler.FLOW_ID_REQUEST_PARAM_NAME: “” (the empty string)

      • If current flow is null and new flow is not null, include the following entries:
        FlowHandler.TO_FLOW_DOCUMENT_ID_REQUEST_PARAM_NAME: The to flow document id
        FlowHandler.FLOW_ID_REQUEST_PARAM_NAME: the flow id for the flow that is the destination of the transition.

      • If the parameters map has entries for either of these keys, both of the entries must be replaced with the new values. This allows the call to FlowHandler.clientWindowTransition() to perform correctly when the GET request after the redirect happens.

      The return from getRedirectURL() is the value to be sent to the client to which the redirect will occur. Call getFlash().setRedirect(true) on the current FacesContext. Cause the current response to perform an HTTP redirect to this path, and call responseComplete() on the FacesContext instance for the current request. If the content of <to-view-id> is a value expression, first evaluate it to obtain the value of the view id.

  • If no matching <navigation-case> element was located, return to Step 1 and find the next matching <navigation-rule> element (if any). If there are no more matching rule elements, execute the following algorithm to search for an implicit match based on the current outcome. This implicit matching algorithm also includes navigating within the current faces flow, and returning from the current faces flow.

    • Let outcome be viewIdToTest.

    • Examine the viewIdToTest for the presence of a “?” character, indicating the presence of a URI query string. If one is found, remove the query string from viewIdToTest, including the leading “?” and let it be queryString, look for the string “faces-redirect=true” within the query string. If found, let isRedirect be true, otherwise let isRedirect be false. Look for the string “includeViewParams=true” or “faces-include-view-params=true”. If either are found, let includeViewParams be true, otherwise let includeViewParams be false. When performing preemptive navigation, redirect is implied, even if the navigation case doesn’t indicate it, and the query string must be preserved. Refer to UIOutcomeTarget for more information on preemptive navigation.

    • If viewIdToTest does not have a “file extension”, take the file extension from the current viewId and append it properly to viewIdToTest.

    • If viewIdToTest does not begin with “/”, take the current viewId and look for the last “/”. If not found, prepend a “/” and continue. Otherwise remove all characters in viewId after, but not including, “/”, then append viewIdToTest and let the result be viewIdToTest.

    • Obtain the current ViewHandler and call its deriveViewId() method, passing the current FacesContext and viewIdToTest. If UnsupportedOperationException is thrown, which will be the case if the ViewHandler is a Pre-Jakarta Faces JSF 1.1 or 1.2 (under the JCP) ViewHandler, the implementation must ensure the algorithm described for ViewHandler.deriveViewId() specified in Default ViewHandler Implementation is performed. Let the result be implicitViewId.

    • If implicitViewId is non-null, discover if fromOutcome is equal to the flow-id of an existing flow in the FlowHandler. If so find the start node of the flow. If the start node is a ViewNode, let viewIdToTest be the vdlDocumentId value of the ViewNode. Call deriveViewId as in the preceding step and let the result be implicitViewId. If fromOutcome is not equal to the flow-id of an existing flow in the FlowHandler, and we are currently in a flow, discover if this is call to a faces-flow-return node. If so, obtain the fromOutcome of the faces-flow-return node, re-apply this algorithm to derive the value of the implicitViewId and continue.

    • If the implicitViewId is non-null, take the following action. If isRedirect is true, append the queryString to implicitViewId. Let implicitNavigationCase be a conceptual <navigation-case> element whose fromViewId is the current viewId, fromAction is passed through from the arguments to handleNavigation(), fromOutcome is passed through from the arguments to handleNavigation(), toViewId is implicitViewId, and redirect is the value of isRedirect, and include-view-params is includeViewParams. Treat implicitNavigationCase as a matching navigation case and return to the first step above that starts with “If a matching <navigation-case> element was located…​”.

  • If UIViewAction.isProcessingBroadcast() returns true, call getFlash().setKeepMessages(true) on the current FacesContext. Compare the viewId of the current viewRoot with the effective <to-view-id> of the matching <navigation-case>. If they differ, take any necessary actions effectively restart the Jakarta Faces lifecycle on the effective <to-view-id> of the matching <navigation-case>. Care must be taken to preserve any view parameters or navigation case parameters, clear the view map of the UIViewRoot, and call setRenderAll(true) on the PartialViewContext.

  • If none of the above steps found a matching <navigation-case>, perform the steps in Requirements for Explicit Navigation in Faces Flow Call Nodes other than ViewNodes to find a matching <navigation-case>.

  • If none of the above steps found a matching <navigation-case>, if ProjectStage is not Production render a message in the page that explains that there was no match for this outcome.

A rule match always causes a new view to be created, losing the state of the old view. This includes clearing out the view map.

Query string parameters may be contributed by three different sources: the outcome (implicit navigation), a nested <f:param> on the component tag (e.g., <h:link>, <h:button>, <h:commandLink>, <h:commandButton>), and view parameters. When a redirect URL is built, whether it be by the N avigationHandler on a redirect case or a UIOutcomeTarget renderer, the query string parameter sources should be consulted in the following order:

  • the outcome (implicit navigation)

  • view parameter

  • nested <f:param>

If a query string parameter is found in two or more sources, the latter source must replace all instances of the query string parameter from the previous source(s).

[P1-end]

7.4.2.1. Requirements for Explicit Navigation in Faces Flow Call Nodes other than ViewNodes

[P1-start ExplicitNavigationNonViewFlowNode requirements] These steps must be performed in this order to determine the vdl view identifier when navigating to a flow node that is not a view node.

Algorithm for resolving a nodeId to a vdl view identifier.

  • If nodeId is a view node, let vdl view identifier be the value of nodeId and exit the algorithm.

  • If the node is a SwitchNode, iterate over the NavigationCase instances returned from its getCases() method. For each, one call getCondition(). If the result is true, let nodeId be the value of its fromOutcome property.

  • If the node is a MethodCallNode, let nodeId be the value invoking the value of its methodExpression property. If the result is null, let nodeId be the value of the MethodCallNode’s outcome property.

  • If the node is a FlowCallNode, save it aside as facesFlowCallNode. Let flowId be the value of its calledFlowId property and flowDocumentId be the value of its calledFlowDocumentId property. If no flowDocumentId exists for the node, let it be the string resulting from flowId + “/” + flowId
    “.xhtml”
    . Ask the FlowHandler for a Flow for this flowId, flowDocumentId pair. Obtain a reference to the start node and execute this algorithm again, on that start node.

  • If the node is a ReturnNode obtain its navigation case and call FlowHandler.pushReturnMode(). This enables the navigation to proceed with respect to the calling flow’s navigation rules, or the application’s navigation rules if there is no calling flow. Start the navigation algorithm over using it as the basis but pass the value of the symbolic constant jakarta.faces.flow.FlowHandler.NULL_FLOW as the value of the toFlowDocumentId argument. If this does not yield a navigation case, call FlowHandler.getLastDisplayedViewId(), which will return the last displayed view id of the calling flow, or null if there is no such flow. In a finally block, when the re-invocation of the navigation algorithms completes, call FlowHandler.popReturnMode().

7.4.2.2. Requirements for Entering a Flow

[P1-start FlowEntryRequirements] If any of the preceding navigation steps cause a flow to be entered, the implementation must perform the following steps, in this order, before continuing with navigation.

  • Make it so any @FlowScoped beans for this flow are able to be activated when an Expression Language expression that references them is evaluated.

  • Call the initializer for the flow, if any.

  • Proceed to the start node of the flow, which may be any flow node type.

An attempt to navigate into a flow other than via the identified start node of that throw should cause a FacesException.

[P1-end]

7.4.2.3. Requirements for Exiting a Flow

[P1-start FlowExitRequirements] If any of the preceding navigation steps cause a flow to be exited, the implementation must perform the following steps, in this order, before continuing with navigation.

  • Call the finalizer for the flow, if any.

  • De-activate any @FlowScoped beans for the current flow.

  • If exiting via a return node ensure the return parameters are correctly passed back to the caller.

[P1-end]

7.4.2.4. Requirements for Calling A Flow from the Current Flow

[P1-start FlowExitRequirements] If any of the preceding navigation steps cause a flow to be called from another flow, the transition() method on FlowHandler will ensure parameters are correctly passed.

[P1-end]

7.4.3. Example NavigationHandler Configuration

The following <navigation-rule> elements might appear in one or more application configuration resources (see Application Configuration Resources) to configure the behavior of the default NavigationHandler implementation:

<navigation-rule>
  <description>
    APPLICATION WIDE NAVIGATION HANDLING
  </description>
  <from-view-id> * </from-view-id>

  <navigation-case>
    <description>
      Assume there is a “Logout” button on every page that
      invokes the logout Action.
    </description>
    <display-name>Generic Logout Button</display-name>
    <from-action>#{userBean.logout}</from-action>
    <to-view-id>/logout.jsp</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      Handle a generic error outcome that might be returned
      by any application Action.
    </description>
    <display-name>Generic Error Outcome</display-name>
    <from-outcome>loginRequired</from-outcome>
    <to-view-id>/must-login-first.jsp</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      Illustrate paramaters
    </description>
    <from-outcome>redirectPasswordStrength</from-outcome>
    <redirect>
      <view-param>
        <name>userId</name>
        <value>someValue</value>
      </view-param>
      <include-view-params>true</include-view-params>
    </redirect>
  </navigation-case>
</navigation-rule>
<navigation-rule>
  <description>
    LOGIN PAGE NAVIGATION HANDLING
  </description>
  <from-view-id> /login.jsp </from-view-id>

  <navigation-case>
    <description>
      Handle case where login succeeded.
    </description>
    <display-name>Successful Login</display-name>
    <from-action>#{userBean.login}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/home.jsp</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      User registration for a new user succeeded.
    </description>
    <display-name>Successful New User Registration</display-name>
    <from-action>#{userBean.register}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/welcome.jsp</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      User registration for a new user failed because of a
      duplicate username.
    </description>
    <display-name>Failed New User Registration</display-name>
    <from-action>#{userBean.register}</from-action>
    <from-outcome>duplicateUserName</from-outcome>
    <to-view-id>/try-another-name.jsp</to-view-id>
  </navigation-case>
</navigation-rule>
<navigation-rule>
  <description>
    Assume there is a search form on every page. These navigation
    cases get merged with the application-wide rules above because
    they use the same “from-view-id” pattern. The same thing would
    also happen if “from-view-id” was omitted here, because that is
    equivalent to a matching pattern of “*”.
  </description>
  <from-view-id> * </from-view-id>

  <navigation-case>
    <display-name>Search Form Success</display-name>
    <from-action>#{searchForm.go}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/search-results.jsp</to-view-id>
  </navigation-case>

  <navigation-case>
    <display-name>Search Form Failure</display-name>
    <from-action>#{searchForm.go}</from-action>
    <to-view-id>/search-problem.jsp</to-view-id>
  </navigation-case>
</navigation-rule>
<navigation-rule>
  <description>
    Searching works slightly differently in part of the site.
  </description>
  <from-view-id> /movies/* </from-view-id>

  <navigation-case>
    <display-name>Search Form Success</display-name>
    <from-action>#{searchForm.go}</from-action>
    <from-outcome>success</from-outcome>
    <to-view-id>/movie-search-results.jsp</to-view-id>
  </navigation-case>

  <navigation-case>
    <display-name>Search Form Failure</display-name>
    <from-action>#\{searchForm.go}</from-action>
    <to-view-id>/search-problem.jsp</to-view-id>
  </navigation-case>
</navigation-rule>
public void savePizza();

<navigation-rule>
  <description>
    Pizza topping selection navigation handling
  </description>
  <from-view-id>/selectToppings.xhtml</from-view-id>

  <navigation-case>
    <description>
      Case where pizza is saved but there is additional cost
    </description>
    <display-name>Pizza saved w/ extras</display-name>
    <from-action>#{pizzaBuilder.savePizza}</from-action>
    <if>#{pizzaBuilder.additionalCost}</if>
    <to-view-id>/approveExtras.xhtml</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      Case where pizza is saved and additional pizzas are needed
    </description>
    <display-name>Pizza saved, additional pizzas needed</display-name>
    <from-action>#{pizzaBuilder.savePizza}</from-action>
    <if>#{not order.complete}</if>
    <to-view-id>/createPizza.xhtml</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      Handle case where pizza is saved and order is complete
    </description>
    <display-name>Pizza complete</display-name>
    <from-action>#{pizzaBuilder.savePizza}</from-action>
    <if>#{order.complete}</if>
    <to-view-id>/cart.xhtml</to-view-id>
  </navigation-case>
</navigation-rule>
public String placeOrder();

<navigation-rule>
  <description>
    Cart navigation handling
  </description>
  <from-view-id>/cart.xhtml</from-view-id>

  <navigation-case>
    <description>
      Handle case where account has one click delivery enabled
    </description>
    <display-name>Place order w/ one-click delivery</display-name>
    <from-action>#{pizzaBuilder.placeOrder}</from-action>
    <if>#{account.oneClickDelivery}</if>
    <to-view-id>/confirmation.xhtml</to-view-id>
  </navigation-case>

  <navigation-case>
    <description>
      Handle case where delivery information is required
    </description>
    <display-name>Place order w/o one-click delivery</display-name>
    <from-action>#{pizzaBuilder.placeOrder}</from-action>
    <if>#{not account.oneClickDelivery}</if>
    <to-view-id>/delivery.xhtml</to-view-id>
  </navigation-case>
</navigation-rule>

7.5. FlowHandler

Any Jakarta Faces application can be modeled as a directed graph where the nodes are views and the edges are transitions between the views. Faces Flows introduces several other kinds of nodes to this directed graph, providing support for encapsulating related views and edges together. Applications can be created as composites of modules of functionality, with each module consisting of well defined entry and exit conditions, and the ability to share state among the nodes within each module. This feature is heavily influenced by the design of ADF Task Flows in Oracle’s Fusion Middleware and also by Spring Web Flow and Apache MyFaces CODI. The normative specification for this feature proceeds from the Javadoc for the class jakarta.faces.flow.FlowHandler, and also from related requirements in NavigationHandler. This section provides a non-normative usage example and walkthrough of feature so that all the other parts of the specification that intersect with this feature can be discovered.

7.5.1. Non-normative example

Here is a simple example to introduce the feature. It does not touch on all aspects of the feature. The example has two flows, each of which calls the other, passing parameters. Any view outside of a flow may navigate to either of the flows, named flow-a and flow-b.

image

This diagram uses the following conventions.

  • view nodes are boxes

  • faces flow return nodes are circles

  • faces flow call nodes are boxes with the corners chopped off

  • @FlowScoped beans are rectangles semi-circular short sides

  • the start node is marked “start”

  • inbound and outbound parameters are listed by name

  • arrows show valid traversals among the nodes.

These flows are identical, except for the names of their constituents, and each has the following properties.

  • Three view nodes, one of which is the implicit start node

  • One faces flow return node, each of which returns the outcome “return1”

  • One flow call node, which calls the other flow, with two outbound parameters, named to match up with the other flow

  • Two inbound parameters, named to match up with the other flow

The different kinds of nodes mentioned in the preceding discussion are defined in the javadoc for class jakarta.faces.flow.FlowHandler.

Consider this simple web app, called basic_faces_flow_call.war, containing the above mentioned flows. The file layout for of the app is shown next. The example is shown using maven war packaging

basic_faces_flow_call/
  pom.xml
  src/main/webapp/
             index.xhtml
             return1.xhtml
             WEB-INF/beans.xml
             flow-a/
               flow-a.xhtml
               next_a.xhtml
               next_b.xhtml
             flow-b/
               flow-b-flow.xml
               next_a.xhtml
               next_b.xhtml
  src/main/java/com/sun/faces/basic_faces_flow_call/
                                FlowA.java
                                Flow_a_Bean.java
                                Flow_b_Bean.java

To complete the example, the execution of the flows is examined. When the application containing these flows is deployed, the runtime discovers the flow definitions and adds them to the internal flow data structure. One flow is defined in flow-b-flow.xml. This is an XML file conforming to the Application Configuration Resources syntax described in Application Configuration Resources. The other flow is defined in FlowA.java, a class with a method with the @FlowDefinition annotation. When the flow discovery is complete, an application scoped, thread safe data structure containing the flow definitions is available from the jakarta.faces.flow.FlowHandler singleton. This data structure is navigable by the runtime via the jakarta.faces.flow.Flow API.

When the user agent visits http://localhost:8080/basic_faces_flow_call/faces/index.xhtml, they see a page with two buttons, the actions of which are flow-a, and flow-b, respectively. Clicking either button causes entry to the corresponding flow. In this case, the user clicks the flow-a button. The @FlowScoped bean Flow_a_Bean is instantiated by the container and navigation proceeds immediately to the start node, in this case flow-a.xhtml. The user proceeds directly to click a button taking them to next_a.xhtml, and then to next_b.xhtml. On that page there is a button whose action is callB. Clicking this button activates the correspondingly named faces flow call node, which prepares the specified outbound parameters, de-activates Flow_a_Bean and calls flow-b.

Upon entry to flow-b, the @FlowScoped bean Flow_b_Bean is instantiated by the container, the outbound parameters from flow-a are matched up with corresponding inbound parameters on flow-b and navigation proceeds immediately to the start node, in this case flow-b.xhtml. The user proceeds directly to click a button taking them to next_a.xhtml, and then to next_b.xhtml. On that page there is a button whose action is taskFlowReturn1. Clicking this button causes Flow_b_Bean to be deactivated and navigation to the view named return1 to be performed.

7.5.2. Non-normative Feature Overview

The normative requirements of the feature are stated in the context of the part of the specification impacted. This section gives the reader a non-normative overview of the feature that touches on all the parts of the specification that intersect with this feature.

Startup Time

At startup time, the runtime will discover flows available for this application. This behavior is normatively specified in Faces Flows and in the XML schema for the application configuration resources.

Invoke Application Time

The default ActionListener may need to take special action when calling into a flow. This behavior is normatively specified in ActionListener Property.

The default NavigationHandler implementation must use the FlowHandler during its operation. This behavior is normatively specified in Default NavigationHandler Algorithm.

7.6. ViewHandler

ViewHandler is the pluggability mechanism for allowing implementations of or applications using the Jakarta Server Faces specification to provide their own handling of the activities in the Render Response and Restore View phases of the request processing lifecycle. This allows for implementations to support different response generation technologies, as well as different state saving/restoring approaches.

A Jakarta Faces implementation must provide a default implementation of the ViewHandler interface. See ViewHandler Property for information on replacing this default implementation with another implementation.

7.6.1. Overview

ViewHandler defines the public APIs described in the following paragraphs

public Locale calculateLocale(FacesContext context);
public String calculateRenderKitId(FacesContext context);

These methods are called from createView() to allow the new view to determine the Locale to be used for all subsequent requests, and to find out which renderKitId should be used for rendering the view.

public void initView(FacesContext) throws FacesException;
public String calculateCharacterEncoding(FacesContext context);

The initView() method must be called as the first method in the implementation of the Restore View Phase of the request processing lifecycle, immediately after checking for the existence of the FacesContext parameter. See the javadocs for this method for the specification.

public String deriveViewId(FacesContext context, String input);

The deriveViewId() method is an encapsulation of the viewId derivation algorithm in previous versions of the specification. This method looks at the argument input, and the current request and derives the viewId upon which the lifecycle will be run.

public UIViewRoot createView(FacesContext context, String viewId);

Create and return a new UIViewRoot instance, initialized with information from the specified FacesContext and view identifier parameters.

If the view being requested is a Facelet view, the createView() method must ensure that the UIViewRoot is fully populated with all the children defined in the VDL page before createView() returns.

public String getActionURL(FacesContext context, String viewId);

Returns a URL, suitable for encoding and rendering, that (if activated) will cause the Jakarta Faces request processing lifecycle for the specified viewId to be executed

public String getBookmarkableURL(FacesContext context, String viewId,
    Map<String,List<String>> parameters, boolean includeViewParams);

Return a Jakarta Faces action URL derived from the viewId argument that is suitable to be used as the target of a link in a Jakarta Faces response. The URL, if activated, would cause the browser to issue an initial request to the specified viewId

public String getRedirectURL(FacesContext context, String viewId,
    Map<String, List<String>> parameters, boolean includeViewParams);

Return a Jakarta Faces action URL derived from the viewId argument that is suitable to be used by the NavigationHandler to issue a redirect request to the URL using an initial request.

public String getResourceURL(FacesContext context, String path);

Returns a URL, suitable for encoding and rendering, that (if activated) will retrieve the specified web application resource.

public void renderView(FacesContext context, UIViewRoot viewToRender)
    throws IOException, FacesException;

This method must be called during the Render Response phase of the request processing lifecycle. It must provide a valid ResponseWriter or ResponseStream instance, storing it in the FacesContext instance for the current request (see ResponseStream and ResponseWriter), and then perform whatever actions are required to cause the view currently stored in the viewRoot of the FacesContext instance for the current request to be rendered to the corresponding writer or stream. It must also interact with the associated StateManager (see StateManager), by calling the getSerializedView() and saveView() methods, to ensure that state information for current view is saved between requests.

public UIViewRoot restoreView(FacesContext context,
    String viewId) throws IOException;

This method must be called from the Restore View phase of the request processing lifecycle. It must perform whatever actions are required to restore the view associated with the specified FacesContext and viewId.

It is the caller’s responsibility to ensure that the returned UIViewRoot instance is stored in the FacesContext as the new viewRoot property. In addition, if restoreView() returns null (because there is no saved state for this view identifier), the caller must call createView(), and call renderResponse() on the FacesContext instance for this request.

public void writeState(FacesContext context) throws IOException;

Take any appropriate action to either immediately write out the current view’s state information (by calling StateManager.writeState()), or noting where state information may later be written. This method must be called once per call to the encodeEnd() method of any renderer for a UIForm component, in order to provide the ViewHandler an opportunity to cause saved state to be included with each submitted form.

public ViewDeclarationLanguage getViewDeclarationLanguage();

See the javadocs for this method for the specification.

public Set<String> getProtectedViewsUnmodifiable();
public void addProtectedView(String urlPattern);
public boolean removeProtectedView(String urlPattern)

See the javadocs for these methods for the specification.

7.6.2. Default ViewHandler Implementation

The terms view identifier and viewId are used interchangeably below and mean the context relative path to the web application resource that produces the view, such as a Jakarta Server Pages page or a Facelets page. In the Jakarta Server Pages case, this is a context relative path to the jsp page representing the view, such as /foo.jsp. In the Facelets case, this is a context relative path to the XHTML page representing the view, such as /foo.xhtml.

Jakarta Faces implementations must provide a default ViewHandler implementation, along with a default ViewDeclarationLanguageFactory implementation that vends ViewDeclarationLanguage implementations designed to support the rendering of Jakarta Server Pages pages containing Jakarta Faces components and Facelets pages containing Jakarta Faces components. The default ViewHandler is specified in this section and the default ViewDeclarationLanguage implementations are specified in the following section.

7.6.2.1. ViewHandler Methods that Derive Information From the Incoming Request

[P1-start ViewHandler.deriveViewId() requirements] The deriveViewId() method must fulfill the following responsibilities:

  • If the argument input is null, return null.

  • If prefix mapping (such as “/faces/*”) is used for FacesServlet, normalize the viewId according to the following algorithm, or its semantic equivalent, and return it.

    • Remove any number of occurrences of the prefix mapping from the viewId. For example, if the incoming value was /faces/faces/faces/view.xhtml the result would be simply view.xhtml.

  • If suffix mapping (such as “*.faces”) is used for FacesServlet, the viewId is set using following algorithm.

    • Let requestViewId be the value of argument input.

    • Consult the javadocs for ViewHandler.FACELETS_VIEW_MAPPINGS_PARAM_NAME and perform the steps necessary to obtain a value for that param (or its alias as in the javadocs). Let this be faceletsViewMappings.

    • Obtain the value of the context initialization parameter named by the symbolic constant ViewHandler.DEFAULT_SUFFIX_PARAM_NAME (if no such context initialization parameter is present, use the value of the symbolic constant ViewHandler.DEFAULT_SUFFIX). Let this be jspDefaultSuffixes. For each entry in the list from jspDefaultSuffixes, replace the suffix of requestViewId with the current entry from jspDefaultSuffixes. For discussion, call this candidateViewId. For each entry in faceletsViewMappings, If the current entry is a prefix mapping entry, skip it and continue to the next entry. If candidateViewId is exactly equal to the current entry, consider the algorithm complete with the result being candidateViewId. If the current entry is a wild-card extension mapping, apply it non-destructively to candidateViewId and look for a physical resource with that name. If present, consider the algorithm complete with the result being the name of the physical resource. Otherwise look for a physical resource with the name candidateViewId. If such a resource exists, consider the algorithm complete with the result being candidateViewId. If there are no entries in faceletsViewMappings, look for a physical resource with the name candidateViewId. If such a resource exists, candidateViewId is the correct viewId.

    • Otherwise, obtain the value of the context initialization parameter named by the symbolic constant ViewHandler.FACELETS_SUFFIX_PARAM_NAME. (if no such context initialization parameter is present, use the value of the symbolic constant ViewHandler.DEFAULT_FACELETS_SUFFIX). Let this be faceletsDefaultSuffix. Replace the suffix of requestViewId with faceletsDefaultSuffix. For discussion, call this candidateViewId. If a physical resource exists with that name, candidateViewId is the correct viewId.

    • Otherwise, if a physical resource exists with the name requestViewId let that value be viewId.

    • Otherwise return null.

  • If an exact mapping (such as /foo) is used for FacesServlet, the viewId is set using following algorithm.

    • Let requestViewId be the value of the argument input.

    • Obtain the value of the context initialization parameter named by the symbolic constant ViewHandler.FACELETS_SUFFIX_PARAM_NAME. (if no such context initialization parameter is present, use the value of the symbolic constant ViewHandler.DEFAULT_FACELETS_SUFFIX). Let this be faceletsDefaultSuffix.

    • Obtain the value of the context initialization parameter named by the symbolic constant ViewHandler.DEFAULT_SUFFIX_PARAM_NAME (if no such context initialization parameter is present, use the value of the symbolic constant ViewHandler.DEFAULT_SUFFIX). Let this be defaultSuffixes.

    • Add faceletsDefaultSuffix to defaultSuffixes.

    • For each entry in the list from defaultSuffixes, add that current entry to the end of requestViewId. For discussion, call this candidateViewId. Look for a physical resource with the name candidateViewId. If such a resource exists, consider the algorithm complete with the result being candidateViewId.

    • Otherwise, if a physical resource exists with the name requestViewId let that value be viewId. Otherwise return null.

  • [P1-end]

The getViewDeclarationLanguage() must fulfill the following responsibilites.

  • See the javadocs for the normative specification for this method.

[P1-start ViewHandler.deriveLogicalViewId() requirements] The deriveLogicalViewId() method is identical to deriveViewId() except that it does not check for the existence of the resource. [P1-end]

[P1-start ViewHandler.calculateCharacterEncoding() requirements] The calculateCharacterEncoding() method must fulfill the following responsibilities:

  • Examine the Content-Type request header. If it has a charset parameter extract it and return it.

  • If not, test for the existence of a session by calling getSession(false) on the ExternalContext for this FacesContext. If the session is non- null, look in the Map returned by the getSessionMap() method of the ExternalContext for a value under the key given by the value of the symbolic constant jakarta.faces.application.ViewHandler.CHARACTER_ENCODING_KEY. If a value is found, convert it to a String and return it. [P1-end]

[P1-start calculateLocale() requirements] The calculateLocale() method must fulfill the following responsibilities:

  • Attempt to match one of the locales returned by the getLocales() method of the ExternalContext instance for this request, against the supported locales for this application as defined in the application configuration resources. Matching is performed by the algorithm described in Section JSTL.8.3.2 of the JSTL Specification. If a match is found, return the corresponding Locale object.

  • Otherwise, if the application has specified a default locale in the application configuration resources, return the corresponding Locale object.

  • Otherwise, return the value returned by calling Locale.getDefault().[P1-end]

[P1-start calculateRenderKitId() requirements] The calculateRenderKitId() method must fulfill the following responsibilities:

  • Return the value of the request parameter named by the symbolic constant ResponseStateManager.RENDER_KIT_ID_PARAM if it is not null.

  • Otherwise, return the value returned by Application.getDefaultRenderKitId() if it is not null.

  • Otherwise, return the value specified by the symbolic constant RenderKitFactory.HTML_BASIC_RENDER_KIT.

7.6.2.2. ViewHandler Methods that are Called to Fill a Specific Role in the Lifecycle

[P1-start createView() requirements] The createView() method must obtain a reference to the ViewDeclarationLanguage for this viewId and call its ViewDeclarationLanguage.createView() method, returning the result and not swallowing any exceptions thrown by that method.[P1-end]

[P1-start initView() requirements] The initView() method must fulfill the following responsibilities:

  • See the javadocs for this method for the specification.[P1-end]

[P1-start renderView() requirements] The renderView() method must obtain a reference to the ViewDeclarationLanguage for the viewId of the argument viewToRender and call its ViewDeclarationLanguage.restoreView() method, returning the result and not swallowing any exceptions thrown by that method.[P1-end]

[P1-start restoreView() requirements]The restoreView() method must obtain a reference to the ViewDeclarationLanguage for the viewId of the argument viewToRender and call its ViewDeclarationLanguage.restoreView() method, returning the result and not swallowing any exceptions thrown by that method.[P1-end]

The writeState() method must fulfill the following responsibilities:

  • Obtain the saved state stored in a thread-safe manner during the invocation of renderView() and pass it to the writeState() method of the StateManager for this application.

7.6.2.3. ViewHandler Methods Relating to Navigation

[P1-start getActionURL() requirements] The getActionURL() method must fulfill the following responsibilities:

  • If the specified viewId does not start with a “/”, throw IllegalArgumentException.

  • If exact mapping (such as /foo) is used for FacesServlet, the following algorithm must be followed to derive the result.

    • Retrieve the collection of existing mappings of the FacesServlet, e.g. using ServletRegistration#getMappings(). Let this be facesServletMappings. If the argument viewId has an extension, then obtain the value of the context initialization parameter named by the symbolic constant ViewHandler.FACELETS_SUFFIX_PARAM_NAME. (if no such context initialization parameter is present, use the value of the symbolic constant ViewHandler.DEFAULT_FACELETS_SUFFIX). Let this be faceletsDefaultSuffix.

    • Obtain the value of the context initialization parameter named by the symbolic constant ViewHandler.DEFAULT_SUFFIX_PARAM_NAME (if no such context initialization parameter is present, use the value of the symbolic constant ViewHandler.DEFAULT_SUFFIX). Let this be defaultSuffixes.

    • Add faceletsDefaultSuffix to defaultSuffixes.

    • For each entry in the list from defaultSuffixes, if the extension of the argument viewId is equal to this entry, remove the extension from viewId. For discussion, call this candidateViewId.

    • Look if the candidateViewId is present in facesServletMappings. If so,the result is contextPath
      candidateViewId
      .

    • If the argument viewId has no extension, then look if the viewId is present in facesServletMappings. If so, the result is contextPath + viewId.

    • If no result has been obtained, pick any prefix mapping or extension mapping from facesServletMappings. If no such mapping is found, throw an IllegalStateException.

    • If such mapping is found remove the "*" character from that mapping, take that as the new mapping and continue with evaluating this mapping as specified below for "if prefix mapping […​] is used" and for "if suffix mapping […​] is used

  • If prefix mapping (such as “/faces/*”) is used for FacesServlet, prepend the context path of the current application, and the specified prefix, to the specified viewId and return the completed value. For example “/cardemo/faces/chooseLocale.jsp”.

  • If suffix mapping (such as “*.faces”) is used for FacesServlet, the following algorithm must be followed to derive the result.

    • If the argument viewId has no extension, the result is contextPath + viewId + mapping, where contextPath is the context path of the current application, viewId is the argument viewId and mapping is the value of the mapping (such as “*.faces”).

    • If the argument viewId has an extension, and this extension is not mapping, the result is contextPath
      viewId.substring(0, period) + mapping
      .

    • If the argument viewId has an extension, and this extension is mapping, the result is contextPath + viewId. For example “/cardemo/chooseLocale.faces

  • If the current view is one of the views to which view protection must be applied, the returned URL must contain the parameter with a name equal to the value of the constant defined by ResponseStateManager.NON_POSTBACK_VIEW_TOKEN_PARAM. The value of this parameter must be the return value from a call to ResponseStateManager.getCryptographicallyStrongTokenFromSession(). This parameter is inspected during the restore view phase (see Restore View).

[P1-end]

[P1-start getBookmarkableURL() requirements] The getBookmarkableURL() method must fulfill the following responsibilities:

  • If argument includeViewParams is true, obtain the view paramaters corresponding to the argument viewId and append them to the Map given in argument parameters. Let the resultant Map be called paramsToEncode.

    • If the viewId of the current FacesContext is not equal to the argument viewId, get the ViewDeclarationLanguage for the argument viewId, obtain its ViewMetadata, call createMetadataView() on it, then call ViewMetadata.getViewParameters() passing the return from createMetadataView(). Let the result of this method be toViewParams.

    • If the viewId of the current FacesContext is equal to the argument viewId, call ViewMetadata.getViewParameters() passing the current UIViewRoot. Let the result of this method be toViewParams.

    • If toViewParams is empty, take no further action to add view parameters to this URL. Iterate over each UIViewParameter element in toViewParams and take the following actions on each element.

    • If the Map given by parameters has a key equal to the name property of the current element, take no action on the current element and continue iterating.

    • If the current UIViewParameter has a ValueExpression under the key “value” (without the quotes), let value be the result of calling getStringValueFromModel() on the current UIViewParameter.

    • Otherwise, if the current viewId is the same as the argument viewId, let value be the result of calling getStringValue() on the current UIViewParameter.

    • Otherwise, if the current viewId is different from the argument viewId, locate the UIViewParameter instance in the current view whose name is equivalent to the current element and let value be the result of calling getStringValue() on the located UIViewParameter.

    • If the above steps yielded a non-null value, find the List<String> value in the parameters map under the key given by the name property of the current UIViewParameter element. If such a List exists, add value to it. Otherwise create a List<String>, add value to it, and add it to the parameters map under the appropriate key.

  • If argument includeViewParams is false, take no action to add additional entries to paramaters. Let paramsToEncode be parameters.

  • Call getActionURL() on the argument viewId. Let the result be actionEncodedViewId.

  • Call encodeBookmarkableURL() on the current ExternalContext, passing actionEncodedViewId as the first argument and paramsToEncode as the second. Let the result be bookmarkEncodedURL.

  • Pass bookmarkEncodedURL to ExternalContext.encodeActionURL() and return the result.[P1-end]

[P1-start getRedirectURL() requirements] The getRedirectURL() method must fulfill the following responsibilities:

  • Take exactly the same action as in getBookmarkableURL() up to and including the call to getActionURL(). Thereafter take the following actions.

  • Call encodeRedirectURL() on the current ExternalContext, passing actionEncodedViewId as the first argument and paramsToEncode as the second. Let the result be redirectEncodedURL.

  • Pass redirectEncodedURL to ExternalContext.encodeActionURL() and return the result.[P1-end]

[P1-start getResourceURL() requirements] The getResourceURL() method must fulfill the following responsibilities:

  • If the specified path starts with a “/”, prefix it with the context path for the current web application, and return the result.

  • Otherwise, return the specified path value unchanged.[P1-end]

7.6.2.4. ViewHandler Methods that relate to View Protection
  • [P1-start addProtectedView() requirements] See the javadocs for addProtectedView() for the normative specification. [P1-end]

  • [P1-start removeProtectedView() requirements] See the javadocs for removeProtectedView() for the normative specification. [P1-end]

  • [P1-start getProtectedViewsUnmodifiable() requirements] See the javadocs for getProtectedViewsUnmodifiable() for the normative specification.

See the View Protection section within Restore View for the normative specification of this feature.

7.7. ViewDeclarationLanguage

To support the introduction of Facelets into the core specification, whilst preserving backwards compatibility with existing Jakarta Server Pages applications, the concept of the View Declaration Language was formally introduced in version 2 of the specification. A View Declaration Language (VDL) is a syntax used to declare user interfaces comprised of instances of Jakarta Faces UIComponents. Under this definition, both Jakarta Server Pages and Facelets are examples of an implementation of a VDL. Any of the responsibilities of the ViewHandler that specifically deal with the VDL sub-system are now the domain of the VDL implementation. These responsibilities are defined on the ViewDeclarationLanguage class.

7.7.1. ViewDeclarationLanguageFactory

ViewDeclarationLanguageFactory is a factory object that creates (if needed) and returns a new ViewDeclarationLanguage instance based on the VDL found in a specific view.

The factory mechanism specified in FactoryFinder and the decoration mechanism specified in Delegating Implementation Support are used to allow decoration or replacement of the ViewDeclarationLanguageFactory.

public ViewDeclarationLanguage getViewDeclarationLanguage(String viewId)

Return the ViewDeclarationLanguage instance suitable for handling the VDL contained in the page referenced by the argument viewId. [P1-start_required_ViewDeclarationLanguageImpls]The default implementation must return a valid ViewDeclarationLanguage instance for views written in either Jakarta Server Pages or Facelets. [P1-end_required_ViewDeclarationLanguageImpls]Whether the instance returned is the same for a Jakarta Server Pages or a Facelet view is an implementation detail.

7.7.2. Default ViewDeclarationLanguage Implementation

For each of the methods on ViewDeclarationLanguage, the required behavior is broken into three segments:

  • Behavior required of all compliant implementations

  • Behavior required of the implementation that handles Facelet views

  • Behavior required of the implementation that handles Jakarta Server Pages views

Any implementation strategy is valid as long as these requirements are met.

7.7.2.1. ViewDeclarationLanguage.createView()
public UIViewRoot createView(FacesContext context, String viewId)

[P1-start createView() requirements] The createView() method must fulfill the following responsibilities.

All implementations must:

  • If there is an existing UIViewRoot available on the FacesContext, this method must copy its locale and renderKitId to this new view root. If not, this method must call calculateLocale() and calculateRenderKitId(), and store the results as the values of the locale and renderKitId, properties, respectively, of the newly created UIViewRoot.

  • If no viewId could be identified, or the viewId is exactly equal to the servlet mapping, send the response error code SC_NOT_FOUND with a suitable message to the client.

  • Create a new UIViewRoot object instance using Application.createComponent(UIViewRoot.COMPONENT_TYPE).

  • Pass the argument viewId to the setViewId() method on the new UIViewRoot instance.

  • The new UIViewRoot instance must be passed to FacesContext.setViewRoot(). This enables the broadest possible range of implementations for how tree creation is actually implemented.

The Jakarta Server Pages and implementation is not required to take any additional action.

The Facelet implementation must call calculateResourceLibraryContracts(), passing the argument viewId, and unconditionally set the result as the resourceLibraryContracts property on the FacesContext. The implementation must obtain the ViewDeclarationLanguage reference on which to invoke calculateResourceLibraryContracts() from the ViewHandler. This ensures the methods can be correctly decorated.

All implementations must:

  • Return the newly created UIViewRoot.

[P1-end]

7.7.2.2. ViewDeclarationLanguage.calculateResourceLibraryContracts()
public List<String> calculateResourceLibraryContracts(
    FacesContext context, String viewId)

The Jakarta Server Pages implementation must return null.

The Facelet implementation must examine the resource library contracts data structure, which was populated as specified in Resource Library Contracts, and find the <contract-mapping> element that matches the argument viewId. When processing the nested <url-pattern> matches must be made using the following rules in this order.

  1. An exact match.

  2. The longest match

  3. The value * matches all incoming viewIds

The value returned from this method is the list whose contents are taken from the contracts attribute of the matching <contract-mapping> element.

7.7.2.3. ViewDeclarationLanguage.buildView()
public void buildView(FacesContext context, UIComponent root)

[P1-start buildView() requirements] The buildView() method must fulfill the following responsibilities.

All implementations must:

  • The implementation must guarantee that the page is executed in such a way that the UIComponent tree described in the VDL page is completely built and populated, rooted at the new UIViewRoot instance created previously.

  • The runtime must guarantee that the view must be fully populated before the afterPhase() method of any PhaseListeners attached to the application or to the UIViewRoot (via UIViewRoot.setAfterPhaseListener() or UIViewRoot.addPhaseListener() ) are called.

The Facelets implementation must guarantee the markup comprising the view is executed with the UIComponent instances in the view being encountered in the same depth-first order as in other lifecycle methods defined on UIComponent, and added to the view (but not rendered at this time), during the traversal. .

[P1-end]

7.7.2.4. ViewDeclarationLanguage.getComponentMetadata()
public BeanInfo getComponentMetadata(
    FacesContext context, Resource componentResource)

[P1-start getComponentMetaData() requirements] The getComponentMetadata() method must fulfill the following responsibilities:

All implementations must:

  • Return a reference to the component metadata for the composite component represented by the argument componentResource, or null if the metadata cannot be found. The implementation may share and pool what it ends up returning from this method to improve performance.

The Facelets implementation must

  • Support argument componentResource being a Facelet markup file that is to be interpreted as a composite component as specified in Composite Component Metadata.

The Jakarta Server Pages implementation is not required to support argument componentResource being a Jakarta Server Pages markup file. In this case, null must be returned from this method.[P1-end]

7.7.2.5. ViewDeclarationLanguage.getViewMetadata() and getViewParameters()
public ViewMetadata getViewMetadata(FacesContext context, String viewId)

[P1-start getViewtMetaData() requirements] The getViewMetadata() method must fulfill the following responsibilities:

All implementations must:

  • Return a reference to the view metadata for the view represented by the argument viewId, or null if the metadata cannot be found. The implementation may share and pool what it ends up returning from this method to improve performance.

The Facelets implementation must support argument viewId being a Facelet markup file from which the view metadata should be extracted.

The Jakarta Server Pages implementation is not required to support argument viewId being a Jakarta Server Pages markup file. In this case, null must be returned from this method.[P1-end]

ViewMetadata Contract
public UIViewRoot createMetadataView()

The content of the metadata is provided by the page author as a special <f:facet/> of the UIViewRoot. The name of this facet is given by the value of the symbolic constant UIViewRoot.METADATA_FACET_NAME. The UIViewRoot return from this method must have that facet, and its children as its only children. This facet may contain <f:viewParameter> or <f:viewAction> children. Each such element is the metadata will cause a UIViewParameter or UIViewAction (respectively) to be added to the view. Because UIViewParameter extends UIInput it is valid to attach any of the kinds of attached objects to an <f:viewParameter> that are valid for any element that represents any other kind of UIInput in the view. Because UIViewAction implements ActionSource2, it is valid to attach any of the kinds of attached objects to an <f:viewAction> that are valid for any element that represents any other kind of ActionSource2 in the view.

]

public Collection<UIViewParameter> getViewParameters(UIViewRoot root)

Convenience method that uses the view metadata specification above to obtain the List<UIViewParameter> for the argument viewId.

7.7.2.6. ViewDeclarationLanguage.getScriptComponentResource()
public Resource getScriptComponentResource(
    FacesContext context, Resource componentResource)

[P1-start getScriptComponentResource() requirements] The getScriptComponentResource() method must fulfill the following responsibilities:

The Facelets implementation must:

  • Take implementation specific action to discover a Resource given the argument componentResource. The returned Resource if non-null, must point to a script file that can be turned into something that extends UIComponent and implements NamingContainer.

The Jakarta Server Pages implementation is not required to support this method. In this case, null must be returned from this method.[P1-end]

7.7.2.7. ViewDeclarationLanguage.renderView()
public void renderView(FacesContext context, String viewId)

[P1-start renderView() requirements] The renderView() method must fulfill the following responsibilities:

All implementations must:

  • Return immediately if calling isRendered() on the argument UIViewRoot returns false.

The Jakarta Server Pages implementation must:

  • If the current request is a ServletRequest , call the set() method of the jakarta.servlet.jsp.jstl.core.Config class, passing the current ServletRequest, the symbolic constant Config.FMT_LOCALE, and the locale property of the specfied UIViewRoot. This configures JSTL with the application’s preferred locale for rendering this response.

  • Update the JSTL locale attribute in request scope so that JSTL picks up the new locale from the UIViewRoot. This attribute must be updated before the JSTL setBundle tag is called because that is when the new LocalizationContext object is created based on the locale.

  • Create a wrapper around the current response from the ExternalContext and set it as the new response in the ExternalContext. Otherwise, omit this step. This wrapper must buffer all content written to the response so that it is ready for output at a later point. This is necessary to allow any content appearing after the <f:view> tag to appear in the proper position in the page.

  • Execute the Jakarta Server Pages page to build the view by treating the viewId as a context-relative path (starting with a slash character), by passing it to the dispatch() method of the ExternalContext associated with this request. Otherwise, continue to the next step. This causes control to pass to the Jakarta Server Pages container, and then to UIComponentClassicTagBase. Please consult the javadocs for that class for the specification of how to handle building the view by executing the Jakarta Server Pages page.

  • Store the wrapped response in a thread-safe manner for use below. Otherwise, omit this step. The default implementation uses the request scope for this purpose.

  • Restore the original response into the ExternalContext.

  • If the FacesContext has a non-null ResponseWriter create a new writer using its cloneWithWriter() method, passing the response’s Writer as the argument. Otherwise, use the current RenderKit to create a new ResponseWriter.

  • Set the new ResponseWriter into the FacesContext, saving the old one aside.

All implementations must:

  • Call saveView() on the StateManager for this application, saving the result in a thread-safe manner for use in the writeState() method of ViewHandler.

  • Call startDocument() on the ResponseWriter.

The Facelets implementation must:

  • Call encodeAll() on the UIViewRoot.

The Jakarta Server Pages implementation must:

  • Output any content in the wrapped response from above to the response, removing the wrapped response from the thread-safe storage.

All implementations must:

  • Call endDocument() on the ResponseWriter.

The Jakarta Server Pages implementation must:

  • If the old ResponseWriter was not null, place the old ResponseWriter back into the FacesContext.

The Facelets implementation must

  • Close the writer used to write the response.[P1-end]

7.7.2.8. ViewDeclarationLanguage.restoreView()
public UIViewRoot restoreView(FacesContext context, String viewId)

[P1-start restoreView() requirements]The restoreView() method must fulfill the following responsibilities:

The Jakarta Server Pages implementation must:

  • If no viewId could be identified, return null.

  • Call the restoreView() method of the associated StateManager, passing the FacesContext instance for the current request and the calculated viewId, and return the returned UIViewRoot, which may be null.

The Facelets implementation must:

  • Call ResponseStateManager.isStateless(). If the result is false, proceed as specified in the Jakarta Server Pages implementation. Otherwise, take the following steps and return.

  • Obtain a reference to the ViewDeclarationLanguage from the ViewDeclarationLanguageFactory. This is necessary to allow for proper decoration. It is not acceptable to simply use the java language this keyword.

  • Call createView() on the ViewDeclarationLanguage instance, passing the context and viewId arguments. Let viewRoot be the result.

  • Call FacesContext.setViewRoot(viewRoot).

  • Call buildView() on the ViewDeclarationLanguage, passing the context and viewRoot.

  • Return the viewRoot.

[P1-end]

7.8. StateManager

StateManager directs the process of saving and restoring the view between requests. The StateManager instance for an application is retrieved from the Application instance, and therefore cannot know any details of the markup language created by the RenderKit being used to render a view. Therefore, the StateManager utilizes a helper object (see ResponseStateManager), that is provided by the RenderKit implementation, and is therefore aware of the markup language details. The Jakarta Faces implementation must provide a default StateManager implementation that supports the behavior described below.

7.8.1. Overview

Conceptually, the state of a view can be divided into two pieces:

  • Tree Structure. This includes component parent-child relationships, including facets.

  • Component State. This includes:

    • Component attributes and properties, and

    • Validators, Converters, FacesListeners, and other objects attached to a component. The manner in which these attached objects are saved is up to the component implementation. For attached objects that may have state, the StateHolder interface (see StateHolder) is provided to allow these objects to preserve their own attributes and properties. If an attached object does not implement StateHolder, but does implement Serializable, it is saved using standard serialization. Attached objects that do not implement either StateHolder or Serializable must have a public, zero-arg constructor, and will be restored only to their initial, default object state 11.

It is beneficial to think of this separation between tree structure and tree state to allow the possibility that implementations can use a different mechanism for persisting the structure than is used to persist the state. For example, in a system where the tree structure is stored statically, as an XML file, for example, the system could keep a DOM representation of the trees representing the webapp UI in memory, to be used by all requests to the application.

7.8.1.1. Stateless Views

Version 2.2 of the specification adds support for stateless views. In such a view, the UIComponent state for the components is not saved. This feature must be used with full awareness of the statefulness requirements of the components in the view. If a component requires state to operate correctly, it must not be used in a stateless view. Furthermore, it is not required that @ViewScoped managed beans work at all with stateless views. This feature only works with Facelet based views, not Jakarta Server Pages based views.

To mark a view as stateless, the existing transient property from UIComponent is exposed to the view author by means of the transient attribute on the <f:view> tag from the Faces Core tag library. The following spec sections contain more normative requirements for stateless views.

  • The vdldocs for the Facelet variant of the <f:view> tag.

  • The javadocs for ResponseStateManager.writeState(FacesContext, Object)

  • The javadocs for ResponseStateManager.isStateless(FacesContext)

  • See ViewDeclarationLanguage.restoreView()

  • The javadocs for jakarta.faces.view.ViewScoped

  • The javadocs for jakarta.faces.bean.ViewScoped

7.8.2. State Saving Alternatives and Implications

Jakarta Faces implementations support two primary mechanisms for saving state, based on the value of the jakarta.faces.STATE_SAVING_METHOD initialization parameter (see Application Configuration Parameters). The possible values for this parameter give a general indication of the approach to be used, while allowing JSF implementations to innovate on the technical details:

  • client — Cause the saved state to be included in the rendered markup that is sent to the client (such as in a hidden input field for HTML). The state information must be included in the subsequent request, making it possible for Jakarta Faces to restore the view without having saved information on the server side. It is advisable that this information be encrypted and tamper evident, since it is being sent down to the client, where it may persist for some time.The default implementation Serializes the view in client mode.

  • server — Cause the saved state to be stored on the server in between requests. Implementations that wish to enable their saved state to fail over to a different container instance must keep this in mind when implementing their server side state saving strategy. Serializing the view in server mode is optional but must be possible by setting the context-param jakarta.faces.SERIALIZE_SERVER_STATE to true. In the server mode, this serialized view is stored in the session and a unique key to retrieve the view is sent down to the client. By storing the serialized view in the session, failover may happen using the usual mechanisms provided by the container.

Serializable in the preceding text means the values of all component attributes and properties (as well as the saved state of attached objects) must implement java.io.Serializable such that if the aggregate saved state were written to an ObjectOutputStream, a NotSerializableException would not be thrown.

7.8.3. State Saving Methods.

public Object saveView(FacesContext context);

[P1-start saveView() requirements] This method causes the tree structure and component state of the view contained in the argument FacesContext to be collected, stored, and returned in a java.lang.Object instance that must implement java.io.Serializable. If null is returned from this method, there is no state to save.[P1-end]

The returned object must represent the entire state of the view, such that a request processing lifecycle can be run against it on postback. Special care must be taken to guarantee that objects attached to component instances, such as listeners, converters, and validators, are also saved. The StateHolder interface is provided for this reason.

This method must also enforce the rule that component ids within a NamingContainer must be unique

public void writeState(FacesContext context, Object state)
    throws IOException;

Save the state represented in the specified Object instance, in an implementation dependent manner.

7.8.4. State Restoring Methods

public UIViewRoot restoreView(FacesContext context, String viewId);

Restore the tree structure and the component state of the view for this viewId to be restored, in an implementation dependent manner. If there is no saved state information available for this viewId, this method returns null.

The default implementation of this method calls through to restoreTreeStructure() and, if necessary restoreComponentState().

7.8.5. Convenience Methods

public boolean isSavingStateInClient(FacesContext context);

[P1-start isSavingStateInClient() requirements] Return true if and only if the value of the ServletContext init parameter named by the value of the constant StateManager.STATE_SAVING_METHOD_PARAM_NAME is equal to the value of the constant STATE_SAVING_METHOD_CLIENT. Return false otherwise.

public String getViewState(FacesContext context);

Return the current view state as a String. [P1-start-getViewState] This method must call ResposeStateManger.getViewState.[P1-end] Refer to ResponseStateManager for more details.

7.9. ResourceHandler

The normative specification for this class is in the javadoc for jakarta.faces.application.ResourceHandler. See also Resource Handling.

public ResourceHandler getResourceHandler();
public void setResourceHandler(ResourceHandler impl);

7.10. Deprecated APIs

7.10.1. PropertyResolver Property

/** @deprecated */
public PropertyResolver getPropertyResolver();

/** @deprecated */
public void setPropertyResolver(PropertyResolver resolver);

[N/T-start getPropertyResolver() requirements] getPropertyResolver() must return a PropertyResolver instance that wraps the ELResolver instance that Faces provides to the unified EL. [N/T-end] The PropertyResolver instance will be utilized to evaluate each . or [] operator when processing value expressions. This method has been deprecated for getELResolver() (see ELResolver Property).

setPropertyResolver() replaces the PropertyResolver instance that will be utilized to evaluate each . or [] operator when processing a value binding expression. A default implementation must be provided, which operates as described in PropertyResolver and the Default PropertyResolver. This method has been deprecated. See the Javadocs for setPropertyResolver().

7.10.2. VariableResolver Property

/** @deprecated */
public VariableResolver getVariableResolver();

/** @deprecated */
public void setVariableResolver(VariableResolver resolver);

[N/T-start getVariableResolver() requirements] getVariableResolver() must return the VariableResolver that wraps the ELResolver instance that Faces provides to the Jakarta Expression Language. The VariableResolver instance will be utilized to convert the first name in a value expression into a corresponding object. The implementation must pass null as the base argument for any methods invoked on the underlying ELResolver. This method has been deprecated for getELResolver(). [N/T-end]

setVariableResolver replaces the VariableResolver instance that will be utilized to resolve method and value bindings. A default implementation must be provided, which operates as described in VariableResolver and the Default VariableResolver. The method has been deprecated. See the Javadocs for setVariableResolver().

7.10.3. Acquiring ValueBinding Instances

/** @deprecated */
public ValueBinding createValueBinding(String ref);

Create and return a ValueBinding that can be used to evaluate the specified value binding expression. Call through to createValueExpression, passing the argument ref, Object.class for the expectedType, and null for the fnMapper. To avoid nondeterministic behavior, it is recommended that applications (or frameworks) wishing to plug in their own resolver implementations do so before createValueBinding() is called for the first time. This method has been deprecated for createValueExpression() (See Programmatically Evaluating Expressions

7.10.4. Acquiring MethodBinding Instances

/** @deprecated */
public MethodBinding createMethodBinding(String ref, Class params[]);

Create and return a MethodBinding that can be used to evaluate the specified method binding expression, and invoke the specified method. The implementation must call through to createMethodExpression, passing the given arguments, and wrap the result in a MethodBinding implementation, returning it. The method that is invoked must have parameter signatures that are compatible with the classes in the params parameter 12 (which may be null or a zero-length array if the method to be called takes no parameters). The actual parameters to be passed when the method is executed are specified on the invoke() call of the returned MethodBinding instance.

To avoid nondeterministic behavior, it is recommended that applications (or frameworks) wishing to plug in their own resolver implementations do so before calling createMethodBinding() for the first time. This method has been deprecated.

7.10.5. Object Factories

/** @deprecated */
public UIComponent createComponent(ValueBinding componentBinding,
    FacesContext context, String componentType);

Special version of the factory for UIComponent instances that is used when evaluating component binding expression properties. The implementation of this method must wrap the argument componentBinding in an implementation of ValueExpression and call through to createComponent(jakarta.el.ValueExpression, jakarta.faces.FacesContext, java.lang.String). This method has been deprecated for createComponent() using ValueExpression (see Object Factories)

7.10.6. StateManager

This method causes the tree structure and component state of the view contained in the argument FacesContext to be collected, stored, and returned in a StateManager.SerializedView instance. If null is returned from this method, there is no state to save.

This method must also enforce the rule that component ids within a NamingContainer must be unique

/** @deprecated */
public void writeState(FacesContext context,
    StateManager.SerializedView state) throws IOException;

Save the state represented in the specified SerializedView instance, in an implementation dependent manner.

/** @deprecated */
protected Object getTreeStructureToSave(FacesContext context);

This method m