13 Using ADF Model in a Fusion Web Application

This chapter describes how an ADF application module's data model and business service interface methods appear at design time for drag and drop data binding, how they are accessible at runtime by the ADF Model data binding layer using the application module data control, and how developers can use the Data Controls panel to create databound pages.

13.1 About ADF Data Binding

ADF Model implements concepts that enable decoupling the user interface technology from the business service implementation: data controls and declarative bindings.

Data controls abstract the implementation technology of a business service by using standard metadata interfaces to describe the service's operations and data collections, including information about the properties, methods, and types involved. In an application that uses business components, a data control is automatically created when you create an application module, and it contains all the functionality of the application module. Developers can then use the representation of the data control displayed in JDeveloper's Data Controls panel to create UI components that are automatically bound to the application module. At runtime, the ADF Model layer reads the information describing the data controls and bindings from the appropriate XML files and then implements the two-way connection between the user interface and the business service.

Declarative bindings abstract the details of accessing data from data collections in a data control and of invoking its operations. There are three basic kinds of declarative binding objects:

Executable bindings: Included in executable bindings are iterator bindings, which simplify the building of user interfaces that allow scrolling and paging through collections of data and drilling-down from summary to detail information. Executable bindings also include bindings that allow searching and nesting a series of pages within another page, as well as bindings that cause operations to occur immediately.

Value bindings: Used by UI components that display data. Value bindings range from the most basic variety that work with a simple text field to more sophisticated list and tree bindings that support the additional needs of list, table, and tree UI controls.

Action bindings: Used by UI components like hyperlinks or buttons to invoke built-in or custom operations on data collections or a data control without writing code.

The group of bindings supporting the UI components on a page are described in a page-specific XML file called the page definition file. The ADF Model layer uses this file at runtime to instantiate the page's bindings. These bindings are held in a request-scoped map called the binding container, accessible during each page request using the EL expression #{bindings}. This expression always evaluates to the binding container for the current page.

Tip:

The current binding container is also available from AdfContext for programmatic access.

You can design a databound user interface by dragging an item from the Data Controls panel and dropping it on a page as a specific UI component. When you use data controls to create a UI component, JDeveloper automatically creates the various code and objects needed to bind the component to the data control you selected.

Note:

Using the ADF Model layer to perform business service access ensures that the view and the business service stay in sync. For example, while you could.call a method on an application module by class-casting the data control reference to the application module instance and then calling the method directly, doing so would bypass the model layer and it would then become unaware of any changes.

13.2 Additional Functionality

You may find it helpful to understand other ADF features before you configure or use the ADF Model layer. Additionally, you may want to read about what you can do with your model layer configurations. Following are links to other functionality that may be of interest.

You can use the ADF Model layer to create your view pages. After reading this chapter for the basic information on how data binding in the view layer works, you should refer to the chapters in Part V, "Creating a Databound Web User Interface" for information about using data binding to create specific view functionality.

13.3 Exposing Application Modules with Oracle ADF Data Controls

The application module data control is a thin adapter over an application module pool that automatically acquires an available application module instance at the beginning of the request. During the current request, the application module data control holds a reference to the application module instance on behalf of the current user session. At the end of the request, the data control releases the instance back to the pool. Importantly, the application module component directly implements the interfaces that the binding objects expect for data collections, built-in operations, and service methods. This optimized interaction allows the bindings to work directly with the application module instances in its data model in the following ways:

Iterator bindings directly bind to the default row set iterator of the default row set of any view object instance. The row set iterator manages the current object and current range information.

Tip:

You can also use the iterator binding to bind to a secondary named row set that you have created. To bind to a secondary row set iterator, you need to use the RSIName. For more information about the difference between the default row set and secondary row sets and how to create them, see Section 42.1.10, "Working with Multiple Row Sets and Row Set Iterators."

Action bindings directly bind to either:

Custom methods on the data control client interface

Built-in operations of the application module and view objects

Figure 13-2 illustrates the pool management role the application module data control plays and highlights the direct link between the bindings and the application module instance.

Figure 13-2 Bindings Connect Directly to View Objects and Methods of an Application Module from a Pool

13.3.1 How an Application Module Data Control Appears in the Data Controls Panel

You use the Data Controls panel to create databound UI components by dragging and dropping icons from the panel onto the visual editor for a page. Figure 13-3 shows the Data Controls panel displaying the data controls for the StoreFront module.

Figure 13-3 Data Controls Panel in JDeveloper

The Data Controls panel lists all the data controls that have been created for the application's business services and exposes all the collections (row sets of data objects), methods, and built-in operations that are available for binding to UI components.

For example, in an application that uses ADF Business Components to define the business services, each data control on the Data Controls panel represents a specific application module, and exposes the view object instances in that application's data model. The hierarchy of objects in the data control is defined by the view links between view objects that have specifically been added to the application module data model. For information about creating view objects and view links, see Chapter 5, "Defining SQL Queries Using View Objects." For information about adding view links to the data model, see Section 5.6.4, "How to Enable Active Master-Detail Coordination in the Data Model."

Tip:

You can open the overview editor for a view object by right-clicking the associated data control object and choosing Edit Definition.

For example, the StoreServiceAMDataControl application module implements the business service layer of the StoreFront module application. Its data model contains numerous view object instances, including several master-detail hierarchies. The view layer of the ADF sample application consists of JSF pages whose UI components are bound to data from the view object instances in the StoreServiceAMDataControl's data model, and to built-in operations and service methods on its client interface.

13.3.1.1 How the Data Model and Service Methods Appear in the Data Controls Panel

Each view object instance appears as a named data collection whose name matches the view object instance name. Figure 13-4 illustrates how the Data Controls panel displays the view object instances in the StoreServiceAMDataControl's data model (note that for viewing simplicity, the figure omits some details in the tree that appear for each view object). The Data Controls panel reflects the master-detail hierarchies in your application module data model by displaying detail data collections nested under their master data collection.

The Data Controls panel also displays each custom method on the application module's client interface as a named data control custom operation whose name matches the method name. If a method accepts arguments, they appear in a Parameters node as operation parameters nested inside the operation's node.

Figure 13-4 How the Data Model Appears in the Data Controls Panel

13.3.1.2 How Transaction Control Operations Appear in the Data Controls Panel

The application module data control exposes two data control built-in operations named Commit and Rollback, as shown in Figure 13-5 (note that the Operations node in the data controls tree omits all of the data collections and custom operations for a more streamlined view). At runtime, when these operations are invoked by the data binding layer, they delegate to the commit() and rollback() methods of the Transaction object associated with the current application module instance.

Note:

In an application module with many view object instances and custom methods, you may need to scroll the Data Controls panel display to find the Operations node that is the direct child node of the data control. This node is the one that contains these built-in operations.

Figure 13-5 How Transaction Control Operations Appear in the Data Controls panel

13.3.1.3 How View Objects Appear in the Data Controls Panel

The view object attributes are displayed as immediate child nodes of the corresponding data collection, as are any custom methods you've created. Figure 13-6 shows how each view object instance in the application module's data model appears in the Data Controls panel. If you have selected any custom methods to appear on the view object's client interface, they appear as custom methods immediately following the view object attributes at the same level. If the method accepts arguments, these appear in a nested Parameters node as operation parameters.

By default, implicit view criteria are created for each attribute that is able to be queried on a view object. They appear as the All Queriable Attributes node under the Named Criteria node, as shown in Figure 13-6. If any named view criteria were created for the view object, they appear under the Named Criteria node. The View Criteria expressions (both implicit and named) appear as method returns. The conjunction used in the query, along with the criteria items and if applicable, any nested criteria, are shown as children. These items are used to create quick search forms, as detailed in Chapter 31, "Creating ADF Databound Search Forms."

Figure 13-6 How View Objects Appear in the Data Controls Panel

As shown in Figure 13-6, the Operations node under the data collection displays all its available built-in operations. If an operation accepts one or more parameters, then those parameters appear in a nested Parameters node. At runtime, when one of these data collection operations is invoked by name by the data binding layer, the application module data control delegates the call to an appropriate method on the ViewObject interface to handle the built-in functionality. The built-in operations fall into three categories: operations that affect the current row, operations that refresh the data collection, and all other operations.

Operations that affect the current row:

Create: Creates a new row that becomes the current row, but does not insert it.

CreateInsert: Creates a new row that becomes the current row, and inserts the new blank row into the data source.

Createwith Parameters: Creates a new row taking parameter values. The passed parameters can supply the create-time value for the following:

A discriminator for a polymorphic view object

A composing parent's foreign key attribute needed for the creation of a polymorphic view object

A composed child view object row when it is not created in the context of a parent row

If you build composite application modules by including nested instances of other application modules, the Data Controls panel reflects this component assembly in the tree hierarchy. For example, assume that, in addition to the StoreServiceAMDataControl application module, you have also created the following application modules in the same package:

An application module named ProductService, and renamed its data control to ProductService

An application module named CompositeService, and renamed its data control to CompositeService

Then assume that you've added two view object instances named OtherViewObject and AnotherViewObject to the data model of CompositeService and that on the Application Modules page of the Edit Application Module dialog you have added an instance of the StoreServiceAMDataControl application module and an instance of the ProductService application module to reuse them as part of CompositeService. Figure 13-7 illustrates how your CompositeService would appear in the Data Controls panel (note that much of the structure of the nested StoreServiceAMDataControl has been omitted for clarity). The nested instances of StoreServiceAMDataControl and ProductService appear in the panel tree display nested inside of the CompositeService data control. The entire data model and set of client methods that the nested application module instances expose to clients are automatically available as part of the CompositeService that reuses them.

One possibly confusing point is that even though you have reused nested instances of StoreServiceAMDataControl and ProductService inside of CompositeService, the StoreServiceAMDataControl and ProductService application modules also appear themselves as top-level data control nodes in the panel tree. JDeveloper assumes that you might want to sometimes use StoreServiceAMDataControl or ProductService on their own as separate data controls from CompositeService, so it displays all three of them. You need to be careful to perform your drag-and-drop data binding from the correct data control. If you want your page to use a view object instance from the nested StoreServiceAMDataControl instance's data model that is an aggregated part of the CompositeService data control, then ensure that you select the data collection that appears as part of the CompositeService data control node in the panel.

It is important to do the drag -and-drop operation that corresponds to your intended usage. When you drop a data collection from the top-levelStoreServiceAMDataControl data control node in the panel, at runtime your page will use an instance of the StoreServiceAMDataControl application module acquired from a pool of StoreServiceAMDataControl components. When you drop a data collection from the nested instance of StoreServiceAMDataControl that is part of CompositeService, at runtime your page will use an instance of the CompositeService application module acquired from a pool of CompositeService components. Since different types of application module data controls will have distinct transactions and database connections, inadvertently mixing and matching data collections from both a nested application module and a top-level data control will lead to unexpected runtime behavior.

13.3.2 How to Open the Data Controls Panel

The Data Controls panel is a panel within the Application Navigator, located at the top left of JDeveloper. To view its contents, click the panel header to expand the panel. If you do not see the panel header, then the Application Navigator may not be displaying.

To open the Application Navigator and Data Controls panel:

From the main menu, choose View > Application Navigator.

To open the Data Controls accordion panel, click the expand icon in the Data Controls header, as shown in Figure 13-8.

Figure 13-8 Data Controls Panel in the Application Navigator

13.3.3 How to Refresh the Data Controls Panel

Any time changes are made to the application module or underlying services, you need to manually refresh the data control in order to view the changes. To refresh the application module data control, click the Refresh icon in the header of the Data Controls panel, as shown in Figure 13-9.

Figure 13-9 Refresh Icon on Data Controls Panel

When you click Refresh, the Data Controls panel looks for all available data controls, and therefore will now reflect any structural changes made to the data control.

13.3.4 Packaging a Data Control for Use in Another Project

You can package up data controls so that they can be used in another project. For example, one development group might be tasked with creating the services and data controls, while another development group might be tasked with creating the UI. The first group would create the services and data controls, and then package them up as an Oracle ADF Library and send it to the second group. The second group can then add the data controls to their project using the Resource Palette. For more information, see Chapter 38, "Reusing Application Components."

13.4 Using the Data Controls Panel

You can design a databound user interface by dragging an item from the Data Controls panel and dropping it on a page as a specific UI component. When you use data controls to create a UI component, JDeveloper automatically creates the various code and objects needed to bind the component to the data control you selected.

In the Data Controls panel, each data control object is represented by a specific icon. Table 13-1 describes what each icon represents, where it appears in the Data Controls panel hierarchy, and what components it can be used to create.

Table 13-1 Data Controls Panel Icons and Object Hierarchy

Icon

Name

Description

Used to Create...

Data Control

Represents a data control. You cannot use the data control itself to create UI components, but you can use any of the child objects listed under it. Depending on how your business services were defined, there may be more than one data control.

Usually, there is one data control for each application module. However, you may have additional data controls that were created for other types of business services (for example, for web services). For information about creating data controls for web services, see Chapter 14, "Exposing Web Services Using the ADF Model Layer."

Serves as a container for the other object and is not used to create anything.

Collection

Represents a named data collection. A data collection represents a set of data objects (also known as a row set) in the data model. Each object in a data collection represents a specific structured data item (also known as a row) in the data model. Throughout this guide, data collection and collection are used interchangeably.

For application modules, the data collection is the default row set contained in a view object instance. The name of the collection matches the view object instance name.

A view link creates a master-detail relationship between two view objects. If you explicitly add an instance of a detail view object (resulting from a view link) to the application module data model, the collection contained in that detail view object appears as a child of the collection contained in the master view object. For information about adding detail view objects to the data model, see Section 5.6.4, "How to Enable Active Master-Detail Coordination in the Data Model."

The children under a collection may be attributes of the collection, other collections that are related by a view link, custom methods that return a value from the collection, or built-in operations that can be performed on the collection.

If you've configured JDeveloper to display viewlink accessor returns, then those are displayed as well.

Represents a discrete data element in an object (for example, an attribute in a row). Attributes appear as children under the collections or method returns to which they belong.

Only the attributes that were included in the view object are shown under a collection. If a view object joins one or more entity objects, that view object's collection will contain selected attributes from all of the underlying entity objects.

Represents a returned object that is neither a Java primitive type (represented as an attribute) nor a collection of any type. An example of a structured attribute would be a domain, which is a developer-created data type used to simplify application maintenance.

For methods that accept parameters: command components and parameterized forms.

Method Return

Represents an object that is returned by a custom method. The returned object can be a single value or a collection.

If a custom method defined in the application module returns anything at all, it is usually a single scalar value. Application module methods do not need to return a set of data to the view layer, because displaying the latest changes to the data is handled by the view objects in the data model (for more information, see Section 3.4, "Overview of the Oracle ADF Active Data Model"). However, custom methods in non-application module data controls (for example, a data control for a CSV file) can return collections to the view layer.

A method return appears as a child under the method that returns it. The objects that appear as children under a method return can be attributes of the collection, other methods that perform actions related to the parent collection, or operations that can be performed on the parent collection.

Represents a built-in data control operation that performs actions on the parent object. Data control operations are located in an Operations node under collections or method returns, and also under the root data control node. The operations that are children of a particular collection or method return operate on those objects only, while operations under the data control node operate on all the objects in the data control.

If an operation requires one or more parameters, they are listed in a Parameters node under the operation.

Select an item in the Data Controls panel and drag it onto the visual editor for your page. For a definition of each item in the panel, see Table 13-1.

Tip:

If you need to drop an operation or method onto a method activity in a task flow, you can simply drag and drop it onto the activity in the diagram.

Tip:

You can use the Filter icon in the Data Controls Panel header to search for a specific item, as shown in Figure 13-10.

Figure 13-10 Filtering the Data Controls Panel

From the ensuing context menu, select a UI component.

When you drag an item from the Data Controls panel and drop it on a page, JDeveloper displays a context menu of all the default UI components available for the item you dropped. The components displayed are based on the libraries in your project.

Figure 13-11 shows the context menu displayed when a data collection from the Data Controls panel is dropped on a page.

Figure 13-11 Data Controls Panel Context Menu

Depending on the component you select from the context menu, JDeveloper may display a dialog that enables you to define how you want the component to look. For example, if you select ADF Read-only Table from the context menu, the Edit Table Columns dialog launches. This dialog enables you to define which attributes you want to display in the table columns, what the column labels are, what types of text fields you want use for each column, and what functionality you want to include, such as row selection or column sorting. For more information about creating tables, see Chapter 27, "Creating ADF Databound Tables."

The UI components selected by default are determined first by any UI control hints set on the corresponding business object. If no control hints have been set, then JDeveloper uses input components for standard forms and tables, and output components for read-only forms and tables. Components for lists are determined based on the type of list you chose when dropping the data control object.

Once you select a component, JDeveloper inserts the UI component on the page in the visual editor. For example, if you drag a collection from the Data Controls panel and choose ADF Read-only Table from the context menu, a read-only table appears in the visual editor, as shown in Figure 13-12.

Figure 13-12 Databound UI Component: ADF Read-Only Table

By default, the UI components created when you use the Data Controls panel use ADF Faces components, are bound to attributes in the ADF data control, and may have one or more built-in features, including:

The default components are fully functional without any further modifications. However, you can modify them to suit your particular needs. Each component and its various features are discussed further in Part V, "Creating a Databound Web User Interface".

Tip:

If you want to change the type of ADF databound component used on a page, the easiest method is to use either the visual editor or the structure window to delete the component, and then drag and drop a new one from the Data Controls panel. When you use the visual editor or the structure window to delete a databound component from a page, if the related binding objects in the page definition file are not referenced by any other component, JDeveloper automatically deletes those binding objects for you (automatic deletion of binding objects will not happen if you use the source editor).

13.4.2 What Happens When You Use the Data Controls Panel

When an Oracle ADF web application is built using the JSF framework, it requires a few additional application object definitions to render and process a page containing ADF databound UI components. If you do not use the Data Controls panel, you will have to manually configure these various files yourself. However, when you use the Data Controls panel, JDeveloper does all of the following required steps:

Creates a DataBindings.cpx file in the default package for the project (if one does not already exist), and adds an entry for the page.

Creates the adfm.xml file in the META-INF directory. This file creates a registry for the DataBindings.cpx file, which allows the application to locate it at runtime so that the binding context can be created.

Adds a page definition file (if one does not already exist for the page) to the page definition subpackage. The default subpackage is view.pageDefs in the adfmsrc directory.

Tip:

You can set the package configuration (such as name and location) in the ADF Model settings page of the Project Properties dialog (accessible by double-clicking the project folder).

The page definition file (pageNamePageDef.xml) defines the ADF binding container for each page in an application's view layer. The binding container provides runtime access to all the ADF binding objects for a page. In later chapters, you will see how the page definition files are used to define and edit the binding object definitions for specific UI components. For more information about the page definition file, see Section 13.7, "Working with Page Definition Files."

Configures the page definition file, which includes adding definitions of the binding objects referenced by the page.

Adds all the libraries, files, and configuration elements required by ADF Faces components. For more information, see the "ADF Faces Configuration" appendix in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

13.4.3 What Happens at Runtime: How the Binding Context Works

When a page contains ADF bindings, at runtime the interaction with the business services initiated from the client or controller is managed by the application through a single object known as the binding context. The binding context is a runtime map (named data and accessible through the EL expression #{data}) of all data controls and page definitions within the application.

The ADF lifecycle creates the Oracle ADF binding context from the application module, DataBindings.cpx, and page definition files, as shown in Figure 13-13. The union of all the DataControls.dcx files and any application modules in the workspace define the available data controls at design time, but the DataBindings.cpx files define what data controls are available to the application at runtime. A DataBindings.cpx file lists all the data controls that are being used by pages in the application and maps the binding containers, which contain the binding objects defined in the page definition files, to web page URLs. The page definition files define the binding objects used by the application pages. There is one page definition file for each page.

The binding context does not contain real live instances of these objects. Instead, the map contains references that become data control or binding container objects on demand. When the object (such as a page definition) is released from the application, for example when a task flow ends or when the binding container or data control is released at the end of the request, data controls and binding containers turn back into reference objects. For information about the ADF lifecycle, see Chapter 25, "Understanding the Fusion Page Lifecycle."

Figure 13-13 ADF File Binding Runtime Usage

13.5 Working with the DataBindings.cpx File

The DataBindings.cpx files define the binding context for the entire application and provide the metadata from which the Oracle ADF binding objects are created at runtime. An application may have more than one DataBindings.cpx file if a component, for example a region, was created outside of the project and then imported. These files map individual pages to page definition files and declare which data controls are being used by the application. At runtime, only the data controls listed in the DataBindings.cpx files are available to the current application.

13.5.1 How JDeveloper Creates a DataBindings.cpx File

The first time you use the Data Controls panel to add a component to a page or an operation to an activity, JDeveloper automatically creates a DataBindings.cpx file in the default package of the view project. It resides in the adfmsrc directory for the project. Once the DataBindings.cpx file is created, JDeveloper adds an entry for the first page or task flow activity. Each subsequent time you use the Data Controls panel, JDeveloper adds an entry to the DataBindings.cpx for that page or activity, if one does not already exist.

13.5.2 What Happens When JDeveloper Creates a DataBindings.cpx File

Once JDeveloper creates a DataBindings.cpx file, you can open it in the overview editor. Figure 13-14 shows the DataBindings.cpx file from the StoreFront module application, as viewed in the overview editor (note that it's been truncated).

Figure 13-14 DataBindings.cpx File in the Overview Editor

Example 13-1 shows an excerpt from the .cpx file in the StoreFront module application.

The Page Mappings section of the editor maps each JSF page or task flow activity to its corresponding page definition file using an ID. The Page Definition Usages section maps the page definition ID to the absolute path for page definition file in the application. The Data Control Usages section identifies the data controls being used by the binding objects defined in the page definition files. These mappings allow the binding container to be initialized when the page is invoked.

You can use the overview editor to change the ID name for page definition files or data controls by double-clicking the current ID name and editing inline. Doing so will update all references in the application. Note, however, that JDeveloper updates only the ID name, it does not update the file name. Be sure that you do not change a data control name to a reserved word. For more information, see Section 9.2.5, "How to Edit an Existing Application Module."

You can also click an element in the Structure window and then use the Property Inspector to change property values. For more information about the elements and attributes in the DataBindings.cpx file, see Section A.7, "DataBindings.cpx."

13.6 Configuring the ADF Binding Filter

The ADF binding filter is a servlet filter that is an instance of the oracle.adf.model.servlet.ADFBindingFilter class. ADF web applications use the ADF binding filter to preprocess any HTTP requests that may require access to the binding context. To do this, the ADF binding filter must be aware of all DataBindings.cpx files that exist for an application.

13.6.1 How JDeveloper Configures the ADF Binding Filter

The first time you add a databound component to a page using the Data Controls panel, JDeveloper automatically configures the filter for you in the application's web.xml file.

13.6.2 What Happens When JDeveloper Configures an ADF Binding Filter

To configure the binding filter, JDeveloper adds the following elements to the web.xml file:

An ADF binding filter class: Specifies the name of the binding filter object, which implements the javax.servlet.Filter interface.

The ADF binding filter is defined in the web.xml file, as shown in Example 13-2. The filter-name element must contain the value adfBindings, and the filter-class element must contain the fully qualified name of the binding filter class, which is oracle.adf.model.servlet.ADFBindingFilter.

Filter mappings: Link filters to static resources or servlets in the web application.

At runtime, when a mapped resource is requested, a filter is invoked. Filter mappings are defined in the web.xml file, as shown in Example 13-3. The filter-name element must contain the value adfBindings.

If you have multiple filters defined in the web.xml file, be sure to list them in the order in which you want them to run. At runtime, the filters are executed in the sequence in which they appear in the web.xml file.

The adfBindings filter should appear after the Trinidad filter and before any filters that depend on the ADF context to be initialized.

13.6.3 What Happens at Runtime: How the ADF Binding Filter Works

At runtime, the ADF binding filter performs the following functions:

Overrides the character encoding when the filter is initialized with the name specified as a filter parameter in the web.xml file. The parameter name of the filter init-param element is encoding.

Instantiates the ADFContext object, which is the execution context for a Fusion web application and contains context information about ADF, including the security context and the environment class that contains the request and response object.

Initializes the binding context for a user's HTTP session. To do this, it first loads the bindings as defined in the DataBindings.cpx file in the current project's adfmsrc directory. If the application contains DataBindings.cpx files that were imported from another project, those files are present in the application's class path. The filter additively loads any auxiliary .cpx files found in the class path of the application.

Notifies data control instances that they are about to receive a request, allowing them to do any necessary per-request setup.

Notifies data control instances after the response has been sent to the client, allowing them to do any necessary per-request cleanup.

13.7 Working with Page Definition Files

Page definition files define the binding objects that populate the data in UI components at runtime. For every page that has ADF bindings, there must be a corresponding page definition file that defines the binding objects used by that page. Page definition files provide design time access to all the ADF bindings. At runtime, the binding objects defined by a page definition file are instantiated in a binding container, which is the runtime instance of the page definition file.

Note:

When multiple windows are open to the same page, the ADF Controller assigns each window its own DataControlFrame. This ensures that each window has its own binding container.

13.7.1 How JDeveloper Creates a Page Definition File

The first time you use the Data Controls panel, JDeveloper automatically creates a page definition file for that page and adds definitions for each binding object referenced by the component. For each subsequent databound component you add to the page, JDeveloper automatically adds the necessary binding object definitions to the page definition file.

By default, the page definition files are located in the view.PageDefs package in the Application Sources directory of the view project. If the corresponding JSF page is saved to a directory other than the default (public_html), or to a subdirectory of the default, then the page definition will also be saved to a package of the same name. For example, if you save your JSF file to the public_html\myDirectory directory, the page definition will be saved to the myDirectory package. You can change the location of the page definition files using the ADF Model Settings page of the Project Properties dialog.

JDeveloper names the page definition files using the following convention:

pageNamePageDef.xml

where pageName is the name of the JSF page. For example, if the JSF page is named home.jsp, the default page definition file name is homePageDef.xml. If you organize your pages into subdirectories, JDeveloper prefixes the directory name to the page definition file name using the following convention:

directoryName_pageNamePageDef.xml

For example, in the StoreFront module, the name of the page definition file for the updateUserInfo page, which is in the account subdirectory of the Web Content node is account_updateUserInfoPageDef.xml.

Tip:

Page definitions for task flows follow the same naming convention.

To open a page definition file, you can right-click directly on the page or activity in the visual editor, and choose Go to Page Definition, or for a JSF page, you can click the Bindings tab of the editor and click the Page Definition File link.

Tip:

While JDeveloper automatically creates a page definition for a JSF page when you create components using the Data Controls panel, or for a task flow when you drop an item onto an activity, it does not delete the page definition when you delete the associated JSF page or task flow activity (this is to allow bindings to remain when they are needed without a JSF page, for example when using desktop integration). If you no longer want the page definition, you need to delete the page definition and all references to it manually. Note however, that as long as a corresponding page or activity is never called, the page definition will never be used to create a binding context. It is therefore not imperative to remove any unused page definition files from your application.

13.7.2 What Happens When JDeveloper Creates a Page Definition File

When JDeveloper creates a paged definition file, it is displayed in the overview editor. Figure 13-15 shows the page definition file in the overview editor that was created for the myOrders.jspx page in the StoreFront module application.

Figure 13-15 Page Definition File in the Overview Editor

The overview editor contains the following tabs, which allow you to view and configure bindings, contextual events, and parameters for a page:

Bindings and Executables: The Bindings and Executables tab of the page definition overview editor shows three different types of objects: bindings, executables, and the associated data controls (note that the data controls do not display unless you select a binding or executable). For example, in Figure 13-15, you can see that the binding for the OrderDate1 attribute uses the MyOrdersIterator iterator to get its value. The iterator accesses the MyOrders collection on the StoreServiceAMDataControl data control. For more information, see Section 13.7.2.2, "Executable Binding Objects Defined in the Page Definition File."

By default, the model binding objects are named after the data control object that was used to create them. If a data control object is used more than once on a page, JDeveloper adds a number to the default binding object names to keep them unique. In Section 13.8, "Creating ADF Data Binding EL Expressions," you will see how the ADF data binding EL expressions reference the binding object names.

Table 13-2 shows the icons for each of the binding objects, as displayed in the overview editor (note that while parameter objects are shown in the Parameter section of the editor, they are also considered binding objects).

Table 13-2 Binding Object Icons

Binding Object Type

Icon

Description

Parameter

Represents a parameter binding object.

Bindings

Represents an attribute value binding object.

Represents a list value binding object.

Represents a tree value binding object.

Represents a method action binding object

Bindings/
Executables

Represents an action binding object. Also represents an invoke action executable binding object and an event.

Executables

Represents an iterator binding object.

Represents a task flow executable binding object.

Contextual Events: You can create contextual events that artifacts in an application can subscribe to. For example, in the StoreFront module, contextual events are used in the customer registration page to display the appropriate informational topic. The register.jspx page contains two regions. One region contains the customer registration task flow, and the other contains the informational topic task flow. A contextual event is passed from the customer registration region to the informational topic region so that the informational topic task flow can display the correct information topic. At design time, the event name, producer region, consumer region, consumer handler, and other information is stored in the event map section of the page definition file.

Parameters: Parameter binding objects declare the parameters that the page evaluates at the beginning of a request. (For more information about the ADF lifecycle, see Chapter 25, "Understanding the Fusion Page Lifecycle.") You can define the value of a parameter in the page definition file using static values, or EL expressions that assign a static value.

Example 13-4 shows how parameter binding objects can be defined in a page definition file.

The value of the filedBy parameter is defined by a binding on the userID data attribute, which would be an attribute binding defined later in the bindings element. The value of the status parameter is defined by an EL expression, which assigns a static value.

Tip:

The EL expression for the parameter values uses the dollar sign ($) because these expressions need to be resolved eagerly, so that the result is returned immediately, as the page is rendered. Most EL expressions in a JSF application use the hash sign (#), which defers the expression evaluation so that the model is prepared before the values are accessed.

When you click an item in the overview editor (or the associated node in the Structure window), you can use the Property Inspector to view and edit the attribute values for the item, or you can edit the XML source directly by clicking the Source tab. Example 13-5 shows abbreviated XML code for the page definition file shown in Figure 13-15.

In later chapters, you will see how the page definition file is used to define and edit the bindings for specific UI components. For a description of all the possible elements and attributes in the page definition file, see Section A.8, "pageNamePageDef.xml."

13.7.2.1 Bindings Binding Objects Defined in the Page Definition File

There are three types of Bindings binding objects used to bind UI components to objects on the data control:

Value: Displays data in UI components by referencing an iterator binding. Each discrete UI component on a page that will display data from the data control is bound to a value binding object. Value binding objects include:

Attribute Values: Binds text fields to a specific attribute in an object (also referred to as an attribute binding object.)

List: Binds the list items to all values of an attribute in a data collection.

Tree: Binds an entire table to a data collection and can also bind the root node of a tree to a data collection.

Button (boolean): Binds a checkbox to a boolean value for an attribute.

Graph: Binds a graph directly to the source data.

Method Action: Binds command components, such as buttons or links, to custom methods on the data control. A method action binding object encapsulates the details about how to invoke a method and what parameters (if any) the method is expecting.

Collectively, the binding objects are referred to as control binding objects, because they work with the UI controls on a page.

Example 13-6 shows a sample bindings element, which defines one action binding called Commit, one attribute binding for a text field called PaymentOptionID1, and one list binding called PaymentTypeCode.

The binding object defined in the action element encapsulates the information needed to invoke the built-in commit operation on the StoreServiceAMDataControl data control. The value of true in the RequiresUpdateModel attribute specifies that the model layer needs to be updated before the operation is executed.

If this operation also raised a contextual event, an event definition would appears well. If the page contained bindings that consumed an event, the event mapping would also appear.

The attributeValues element defines the value bindings for the text fields on the page. In the example, the PaymentOptionId1 attribute binding will display the value of the PaymentOptionId, which is defined in the AttrNames element. The IterBinding attribute references the iterator binding that manages the data to be displayed in the text field (for more information, see Section 13.7.2.2, "Executable Binding Objects Defined in the Page Definition File").

Iterator: Binds to an iterator that iterates over view object collections. There is one iterator binding for each collection used on the page. All of the value bindings on the page must refer to an iterator binding in order for the component values to be populated with data at runtime.

When you drop a collection or an attribute of a collection on the page, an iterator binding is automatically added as an executable. Iterator binding objects bind to an underlying ADF RowSetIterator object, which manages the current object and current range information. The iterator binding exposes the current object and range state to the other binding objects used by the page.

The iterator range represents the current set of objects to be displayed on the page. The maximum number of objects in the current range is defined in the rangeSize attribute of the iterator. For example, if a collection in the data control contains products and the iterator range size is 25, the first 25 products in the collection are displayed on the page. If the user scrolls down, the next set of 25 is displayed, and so on. If the user scrolls up, the previous set of 25 is displayed. If your view object uses range paging, then you can configure the iterator binding to return a set of ranges at one time. For more information, see Section 42.1.5, "Efficiently Scrolling Through Large Result Sets Using Range Paging."

Note:

If you have two pages each with an iterator binding bound to the iterator on the same view object (which you will if you drop the same collection, for example, on two different pages), then you should ensure that the rangeSize attribute is the same for both pages' iterator bindings. If not, the page with a smaller range size may cause the iterator to reexecute, causing unexpected results on the other page.

Method Iterator: Binds to an iterator that iterates over the collections returned by custom methods in the data control.

A method iterator binding is always related to a method action binding object. The method action binding encapsulates the details about how to invoke the method and what parameters (if any) the method is expecting. The method action binding is itself bound to the method iterator, which provides the data.

You will see method iterator executable binding objects only if you drop a method return collection or an attribute of a method return collection from a custom method on the data control. If you are using only application module data controls, you will see only iterator binding objects.

Variable Iterator: Binds to an iterator that exposes all the variables in the binding container to the other bindings. While there is an iterator binding for each collection, there is only one variable iterator binding for all variables used on the page. (The variable iterator is like an iterator pointing to a collection that contains only one data object whose attributes are the binding container variables.)

Page variables are local to the binding container and exist only while the binding container object exists. When you use a data control method (or an operation) that requires a parameter that is to be collected from the page, JDeveloper automatically defines a variable for the parameter in the page definition file. Attribute bindings can reference the page variables.

A variable iterator can contain one of two types of variables: variable and variableUsage. A variable type variable is a simple value holder, while a variableUsage type variable is a value holder that is related to a view object's named bind parameter. Defining a variable as a variableUsage type allows it to inherit the default value and UI control hints from the view object named bind variable to which it is bound.

Invoke Action: Binds to a method that invokes the operations or methods defined in action or method action bindings during any phase of the page lifecycle.

Tip:

If you know you want a method to execute before the page is rendered, you should use a method call activity in the task flow to invoke the method, rather than an invoke action in the page definition file. Using the method call activity makes invoking page logic easier, and allows you to show more information on the task flow, making the diagram more readable and useful to anyone else who might be using it. However, if you need the method to be executed in more than one phase of the page's lifecycle, or if you plan to reuse the page and page definition file and want the method to be tied to the page, or if your application does not use ADFc, then you should use an invoke action to invoke the method.

You can also use the page element to bind to another page definition file. However, at runtime, only the current incoming page's (or if the rendered page is different from the incoming, the rendered page's) binding container is automatically prepared by the framework during the current request. Therefore, to successfully access a bound value in another page from the current page, you must programmatically prepare that page's binding container in the current request (for example, using a backing bean). Otherwise, the bound values in that page may not be available or valid in the current request.

Search Region: Binds named criteria to the iterator, so that the search can be executed.

Multi Task Flow: instantiates the binding container for a region's task flow from an array of task flows. This is useful when you have a page that contains an unknown number of regions, for example a a panelTabbed component where each tab is a region, and users can add and delete tabs at runtime. For more information, see Section 21.10, "Configuring a Page To Render an Unknown Number of Regions."

At runtime, executable bindings are refreshed based on the value of their Refresh attribute. Refreshing an iterator binding reconnects it with its underlying RowSetIterator object. Refreshing an invoke action binding invokes the action. Before refreshing any bindings, the ADF runtime evaluates any Refresh and RefreshCondition attributes specified in the executables. The Refresh attribute specifies the ADF lifecycle phase within which the executable should be invoked. The RefreshCondition attribute specifies the conditions under which the executable should be invoked. You can specify the RefreshCondition value using a boolean EL expression. If you leave the RefreshCondition attribute blank, it evaluates to true.

By default, the Refresh value is set to deferred. This means the binding will not be executed unless its value is accessed (for example by an EL expression on a JSF page). Once called, it will not reexecute unless any parameter values for the binding have changed, or if the binding itself has changed.

The iterator binding named MyOrderItems was created by dropping the MyOrderItems collection on the page as a table. The iterator binding named MyOrders was created by dropping the MyOrders collection, which has a master-detail relationship with the MyOrderItems collection. For more information, see Chapter 29, "Displaying Master-Detail Data."

The Binds attribute of the iterator element defines the collection the iterator will iterate over. The RangeSize attribute defines the number of objects the iterator is to display on the page at one time. A RangeSize value of -1 causes the iterator to display all the objects from the collection.

Tip:

Normally, an iterator binding's default range size is 25. However, when an iterator binding is created from the Edit List Binding dialog, the range size defaults to -1 so that all choices display in the list, not just the first 25.

Performance Tip:

When you want to reduce the number of roundtrips the iterator requires to fetch the data objects from the view object in the ADF Business Components layer, you can set the rangeSize attribute to -1, and the objects will be fetched in a single round trip to the server, rather than in multiple trips as the user navigates through the objects.

13.8 Creating ADF Data Binding EL Expressions

To display data from the data model, web page UI components are bound to binding objects using JSF Expression Language (EL) expressions. These EL expressions reference a specific binding object in a binding container. At runtime, the JSF runtime evaluates an EL expression and pulls the value from the binding object to populate the component with data when the page is displayed. If the user updates data in the UI component, the JSF runtime pushes the value back into the corresponding binding object based on the same EL expression.

Tip:

There may be cases when you need to use EL expressions within managed beans. For information on working with EL expressions within managed beans, see the "Creating EL Expressions" section in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

13.8.1 How to Create an ADF Data Binding EL Expression

When you use the Data Controls panel to create a component, the ADF data binding expressions are created for you. The expressions are added to every component attribute that will either display data from or reference properties of a binding object. Each prebuilt expression references the appropriate binding objects defined in the page definition file. You can edit these binding expressions or create your own, as long as you adhere to the basic ADF binding expression syntax. ADF data binding expressions can be added to any component attribute that you want to populate with data from a binding object.

In JSF pages, a typical ADF data binding EL expression uses the following syntax to reference any of the different types of binding objects in the binding container:

#{bindings.BindingObject.propertyName}

where:

bindings is a variable that identifies that the binding object being referenced by the expression is located in the binding container of the current page. All ADF data binding EL expressions must start with the bindings variable.

BindingObject is the ID, or for attributes the name, of the binding object as it is defined in the page definition file. The binding objectID or name is unique to that page definition file. An EL expression can reference any binding object in the page definition file, including parameters, executables, or value bindings.

For example, in the following expression that might appear on a JSF page:

#{bindings.ProductName.inputValue}

the bindings variable references a bound value in the current page's binding container. The binding object being referenced is ProductName, which is an attribute binding object. The binding property is inputValue, which returns the value of the first ProductName attribute.

Tip:

While the binding expressions in the page definition file can use either a dollar sign ($) or hash sign (#) prefix, the EL expressions in JSF pages can use only the hash sign (#) prefix.

As stated previously, when you use the Data Controls panel to create UI components, these expressions are built for you. However, you can also manually create them if you need to. The JDeveloper Expression Builder is a dialog that helps you build EL expressions by providing lists of binding objects defined in the page definition files, as well as other valid objects to which a UI component may be bound. It is particularly useful when creating or editing ADF databound expressions because it provides a hierarchical list of ADF binding objects and their most commonly used properties. For information about binding properties, see Section 13.8.2, "What You May Need to Know About ADF Binding Properties."

13.8.1.1 Opening the Expression Builder from the Property Inspector

You can select an item in the visual editor, and then create EL expressions for specific attributes using the Property Inspector.

To open the Expression Builder from the Property Inspector:

Select a UI component in the Structure window or the visual editor.

In the Property Inspector, click the dropdown list next to a field, and choose Expression Builder.

13.8.1.2 Using the Expression Builder

Once the Expression Builder is open, you can use it to create EL expressions.

Use the Expression Builder to edit or create ADF binding expressions using the following features:

Use the Variables tree to select items that you want to include in the binding expression. The tree contains a hierarchical representation of the binding objects. Each icon in the tree represents various types of binding objects that you can use in an expression (see Table 13-3 for a description of each icon).

To narrow down the tree, you can either use the dropdown filter or enter search criteria in the search field. Double-click an item in the tree to move it to the Expression box.

Use the operator buttons to add logical or mathematical operators to the expression.

Tip:

You can also type the expression directly in the Expression box.

Table 13-3 Icons Under the ADF Bindings Node of the Expression Builder

Icon

Description

Represents the bindings container variable, which references the binding container of the current page. Opening the bindings node exposes all the binding objects for the current page.

Represents the data binding variable, which references the entire binding context (created from all the .cpx files in the application). Opening the data node exposes all the page definition files in the application.

Represents an action binding object. Opening a node that uses this icon exposes a list of valid action binding properties.

Represents an iterator binding object. Opening a node that uses this icon exposes a list of valid iterator binding properties.

Represents an attribute binding object. Opening a node that uses this icon exposes a list of valid attribute binding properties.

Represents a list binding object. Opening a node that uses this icon exposes a list of valid list binding properties.

Represents a table or tree binding object. Opening a node that uses this icon exposes a list of valid table and tree binding properties.

13.8.2 What You May Need to Know About ADF Binding Properties

When you create a databound component using the Expression Builder, the EL expression might reference specific ADF binding properties. At runtime, these binding properties can define such things as the default display characteristics of a databound UI component or specific parameters for iterator bindings. The ADF binding properties are defined by Oracle APIs. For a full list of the available properties for each binding type, see Appendix B, "Oracle ADF Binding Properties."

Values assigned to certain properties are defined in the page definition file. For example, iterator bindings have a property called RangeSize, which specifies the number of rows the iterator should display at one time. The value assigned to RangeSize is specified in the page definition file, as shown in Example 13-8.

13.9 Using Simple UI First Development

While the Data Controls panel enables you to design and create bound components in a single drag-and-drop action, in some cases, it may be preferable to create the basic UI components first and add the bindings later. For example, if your page will use declarative components, you will first need to drop the declarative component, and then bind it to the correct ADF control. Declarative components are reusable, composite UI components that are made up of other ADF Faces components. Once imported into a project, declarative components can be dropped onto a page from the Component Palette, similar to standard ADF Faces components. While the entire declarative component cannot use ADF data binding, you can use ADF data binding on the individual components that make up the declarative component, once the declarative component is dropped on the page. For more information about declarative components, see the "Using Declarative Components" section of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

Note:

If you know the UI components on your page will eventually use ADF data binding, but you need to develop the pages before the data controls are ready, then you should consider using placeholder data controls, rather than manually binding the components. Using placeholder data controls will provide the same declarative development experience as using developed data controls. For more information, see Chapter 17, "Designing a Page Using Placeholder Data Controls."

When designing web pages, keep in mind that ADF bindings can be added only to certain ADF Faces tags or their equivalent JSF HTML tags. Table 13-4 lists the ADF Faces and JSF tags to which you can later add ADF bindings.

Tip:

To enable the use of JSF Reference Implementation UI component tags with ADF bindings, you must choose the Include JSF HTML Widgets for JSF Databinding option in the ADF View Settings of the project properties. However, using ADF Faces tags, especially with ADF bindings, provides greater functionality than does using the reference implementation JSF tags.

Table 13-4 Tags That Can Be Used for ADF Bindings

ADF Faces Tags Used in ADF Bindings

Equivalent JSF HTML Tags

Text Fields

af:inputText

h:inputText

af:outputText

h:outputText

af:outputLabel

h:outputLabel

af:inputDate

n/a

Tables

af:table

h:dataTable

Actions

af:commandButton

h:commandButton

af:commandLink

h:commandLink

af:commandMenuItem

n/a

af:commandToolbarButton

n/a

Selection Lists

af:inputListOfValues

n/a

af:selectOneChoice

h:selectOneMenu

af:selectOneListbox

h:selectOneListbox

af:selecOneRadio

h:selectOneRadio

af:selectBooleanCheckbox

h:selectBooleanCheckbox

Queries

af:query

n/a

af:quickQuery

n/a

Trees

af:tree

n/a

af:treeTable

n/a

Before adding binding to the UI components, ensure that you follow these guidelines:

When creating the JSF page using the Create JSF JSP wizard, choose the Do not Automatically Expose UI Components in a Managed Bean option on the Managed Bean tab.

This option turns off JDeveloper's auto-binding feature, which automatically associates every UI component in the page to a corresponding property in the backing bean for eventual programmatic manipulation. If you intend to add ADF bindings to a page, do not use the auto-binding feature. If you use the auto-binding feature, you will have to remove the managed bean bindings later, after you have added the ADF bindings. The managed bean UI component property bindings do not affect the ADF bindings, but their presence may be confusing in the JSF code. For information about managed beans, see Section 24.4, "Using a Managed Bean in a Fusion Web Application."

Add the ADF Faces tag libraries.

While you can add ADF bindings to JSF components, the ADF Faces components provide greater functionality, especially when combined with ADF bindings.

13.9.1 How to Apply ADF Model Data Binding to Existing UI Components

You apply ADF model binding to components using the Structure window.

To apply ADF Model data binding:

In the Design page of the visual editor, select the UI component to which you want to add ADF bindings.

The component must be one of the tags listed in Table 13-4. When you select a component in the visual editor, JDeveloper simultaneously selects that component tag in the Structure window, as shown in Figure 13-16.

Figure 13-16 The Structure Window in JDeveloper

In the Structure window, right-click the UI component, and from the context menu, choose Bind to ADF Control.

In the Bind to ADF Control dialog, select the data control to which you want the UI component bound. JDeveloper will notify you if you choose a control that is not compatible with the selected UI component.

13.9.2 What Happens When You Apply ADF Model Data Binding to UI Components