2 Using ADF Model Data Binding in a Java EE Web Application

ADF Model is a declarative data binding facility that enables a unified approach to binding user interfaces to business services without requiring code.

This chapter provides a brief overview of ADF Model data binding in Java EE applications. For information on configuring the business services that you will bind to UI components, see Chapter 3, "Adding Business Logic to Data Controls." For more comprehensive information about using ADF Model data binding, refer to the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

This chapter includes the following sections:

2.1 Introduction to ADF Model Data Binding

ADF Model implements two concepts that enable the decoupling of 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 an EJB session facade, developers can create data controls for the facade. Developers can then use the representation of the data control displayed in JDeveloper's Data Controls panel (as shown in Figure 2-1) to create UI components that are automatically bound to the session facade. 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.

Figure 2-1 Data Controls Panel

High-level nodes for a data control

Declarative bindings abstract the details of accessing data from data collections in a data control and of invoking its operations. The following are the basic categories of binding objects:

  • 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 command components like hyperlinks or buttons to invoke built-in or custom operations on data collections or a data control without writing code.

  • Executable bindings: Include iterator bindings, which are mainly used in the background to manage the query and the current row. 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.

Figure 2-2 shows how bindings connect UI components to data control collections and methods.

Figure 2-2 Bindings Connect UI Components to Data Controls

binding between a data control and page

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. In a JSF application, the binding container is accessible during each page request using the EL expression #{bindings}. Example 2-1 shows the code used for binding a checkbox in a form to the orderFilled attribute of the OrdersSessionEJBLocal data control.

Example 2-1 Binding Code for a Checkbox in a JSF Web Page

<af:selectBooleanCheckbox value="#{bindings.orderFilled.inputValue}"
                   label="#{bindings.orderFilled.label}"
                   shortDesc="#{bindings.orderFilled.hints.tooltip}" id="sbc1"/>

Tip:

For more information about ADF EL expressions, see the "Creating ADF Data Binding EL Expressions" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

To use the ADF Model layer to bind data, you need to use JDeveloper to create a data control for your services. The data control will then appear as a tree hierarchy in the Data Controls panel where each subnode in the tree represents a collection, operation, method or attribute. You can then create databound components by dragging and dropping those subnodes onto the visual editor for a web page or other user interface component. For example, you can create databound HTML elements for JSP pages, databound UI components for JSF pages, and databound Swing UI components for ADF Swing panels. When you drag a subnode from a data control to a page, JDeveloper automatically creates the metadata that describes the bindings from the page to the services. At runtime, the ADF Model layer reads the metadata information from the appropriate XML files for both the data controls and the bindings, and then implements the two-way connection between your user interface and your business services.

2.2 Exposing Business Services with ADF Data Controls

Once you have your application's services in place, you can use JDeveloper to create data controls that provide the information needed to declaratively bind UI components to those services. In a Java EE application, you normally create entity beans that represent tables in a database and then create a session facade over all the EJBs. This facade provides a unified interface to the underlying entities. In an Oracle ADF application, you can create a data control for the session bean, and that data control will contain representation of all the EJBs under the session bean.

You generate data controls with the Create Data Control command. Data controls consist of one or more XML metadata files that define the capabilities of the services that the bindings can work with at runtime. The data controls work in conjunction with the underlying beans without changing the implementation of the beans.

For example, the Summit demo application uses the summit database schema, which contains a number of relational database tables. The application's Model project has a number of entity beans that represent the tables in the schema used by the Summit demo application. There is a Customer bean, a Product bean, an Order bean, and so on. The module also contains a session bean, OrdersSessionEJBBean, which is used to access the beans created from tables. There is a data control for the session bean, which allows developers to declaratively create UI pages using the data and logic contained in the session bean and in the entity beans that the session bean encapsulates.

2.2.1 How to Create ADF Data Controls

You create data controls from within the Application Navigator of JDeveloper.

Before you begin:

It may be helpful to have a general understanding of using data controls. For more information, see Section 2.2, "Exposing Business Services with ADF Data Controls.".

You will need to complete this task:

Create an application workspace, JPA/EJB 3.0 entities, and one or more session beans for the entities. For more information, see the "How to Work with an EJB Business Services Layer" section of the Oracle Fusion Middleware User's Guide for Oracle JDeveloper.

Note:

You can also base a data control on a Java Service Facade class. With a Java Service Facade, you can expose business methods either from within an EJB container or without using an EJB container. A Java Service Facade template is available in the New Gallery. Also note that any class on which you base a data control must meet the JavaBeans specification. In particular, the class must have a public default constructor.

To create a data control:

  1. In the Application Navigator, right-click the session bean for which you want to create a data control and choose Create Data Control from the context menu.

  2. In the Choose EJB Interface dialog, choose Local or Remote. For web applications, typically you would choose Local.

    Note:

    If you later rename the bean on which a data control is based, you must again use the Create Data Control command in order to regenerate the data control's metadata.

    If you merely make changes to a bean after the data control is created, you do not have to regenerate the data control. The data control incorporates any changes made to the bean. However, you might need to close and reopen the project in order for the data control to incorporate the changes to the underlying beans.

2.2.2 What Happens in Your Project When You Create a Data Control

When you create a data control based on an EJB session bean, JDeveloper creates the data control definition file (DataControls.dcx), opens the file in the overview editor, and displays the file's hierarchy in the Data Controls panel. This file enables the data control to work directly with the services and the bindings. Figure 2-3 shows the DataControls.dcx file in the overview editor.

Figure 2-3 DataControls.dcx File in the Overview Editor

Overview editor for the DataControls.dcx file

Example 2-2 shows the code from the corresponding XML file, which you can view by clicking on the Source tab in the editor window.

Example 2-2 DataControls.dcx File

<?xml version="1.0" encoding="UTF-8" ?>
<DataControlConfigs xmlns="http://xmlns.oracle.com/adfm/configuration" version="11.1.2.58.66" id="DataControls"
                    Package="model">
  <AdapterDataControl id="OrdersSessionEJBLocal" FactoryClass="oracle.adf.model.adapter.DataControlFactoryImpl"
                      ImplDef="oracle.adfinternal.model.adapter.ejb.EjbDCDefinition" SupportsTransactions="false"
                      SupportsSortCollection="true" SupportsResetState="false" SupportsRangesize="false"
                      SupportsFindMode="false" SupportsUpdates="true" Definition="model.OrdersSessionEJBLocal"
                      BeanClass="model.OrdersSessionEJBLocal" xmlns="http://xmlns.oracle.com/adfm/datacontrol">
    <CreatableTypes>
      <TypeInfo FullName="model.Product"/>
      <TypeInfo FullName="model.Item"/>
      <TypeInfo FullName="model.Ord"/>
      <TypeInfo FullName="model.Customer"/>
      <TypeInfo FullName="model.Emp"/>
    </CreatableTypes>
    <Source>
      <ejb-definition ejb-version="3.0" ejb-name="OrdersSessionEJB" ejb-type="Session"
                      ejb-business-interface="model.OrdersSessionEJBLocal" ejb-interface-type="local"
                      initial-context-factory="weblogic.jndi.WLInitialContextFactory"
                      DataControlHandler="oracle.adf.model.adapter.bean.jpa.JPQLDataFilterHandler"
                      xmlns="http://xmlns.oracle.com/adfm/adapter/ejb"/>
    </Source>
  </AdapterDataControl>
</DataControlConfigs>

2.2.2.1 DataControls.dcx Overview Editor

The overview editor for the DataControls.dcx file provides a view of the master-detail hierarchies of your data model as well as methods from the session facade. When you select a node, you can view the fields that can be mapped to database columns in the corresponding entity class in the Attributes tab. In the Accessors tab, you can view fields for the corresponding entity class that have entity relationships defined (such as OneToMany and ManyToOne). In the Operations tab, you can view methods that operate on the entities, such as the add and remove methods of the collection accessors.

See Table 2–1 for a description of the icons that are used in the overview editor and Data Controls panel.

You can change the settings for a data control by selecting an element and clicking the Edit icon. For more information about editing a data control, see Section 3.2, "Configuring Data Controls."

2.2.2.2 Data Controls Panel

The Data Controls panel appears in the Application Navigator once you have created a data control. The Data Controls panel serves as a palette, from which you can create databound UI components by dragging nodes from the Data Controls panel to the design editor for a web page.

Similar to the DataControls.dcx overview editor, the Data Controls panel reflects the master-detail hierarchies in your data model by displaying detail data collections nested under their master data collection. For example, Figure 2-4 shows the Data Controls panel with the data control for the Summit demo application. The Customer, Emp, Item, Ord, and Product beans are all represented by accessor returned collections in the figure, which in turn correspond to named queries defined in the beans.

Figure 2-4 Data Controls Panel

Data Control panel with nodes from the Summit demo

The Data Controls panel also displays each service method on the session bean as a method icon whose name matches the method name. If a method accepts arguments, those arguments appear in a Parameters node as parameters nested inside the method's node. Objects that are returned by the methods appear as well, as shown in Figure 2-4.

In addition to the nodes that are displayed in the overview editor for the DataControls.dcx file, the Data Controls panel displays nodes for other objects that are available for binding, such as entity bean attributes, built-in operations, and method parameters.

Tip:

If the Data Controls panel is not visible, see the "How to Open the Data Controls Panel" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework for instructions on opening the panel.

Each returned collection or object displays any attributes and custom methods that were defined on the associated bean. Figure 2-5 shows the attributes and methods defined on the Item bean that is returned by the itemFindAll accessor method.

Figure 2-5 Child Nodes to Returned Collections

Child nodes to an accessor returned collection

By default, implicit named criteria are created for each attribute that is able to be queried on a bean. They appear in the Data Controls panel as the All Queriable Attributes node under the Named Criteria node, as shown in Figure 2-5. This node is used to create quick search forms, as detailed in Chapter 8, "Creating Databound Search Forms."

As shown in Figure 2-5, the Operations node under a returned collection in the Data Controls panel displays all its available built-in operations that are provided by the data control. 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 data control delegates the call to an appropriate method on the bean interface to handle the built-in functionality. Most of the built-in operations affect the current row. However, the execute operation refreshes the data control itself, and the commit and rollback operations affect all changes made within the boundaries of a transaction. Following are the built-in operations:

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

  • Delete: Deletes the current row.

  • Execute: Refreshes the data collection by executing or reexecuting the accessor method.

  • First: Sets the first row in the row set to be the current row.

  • Last: Sets the last row in the row set to be the current row.

  • Next: Sets the next row in the row set to be the current row.

  • Next Set: Navigates forward one full set of rows.

  • Previous: Sets the previous row in the row set to be the current row.

  • Previous Set: Navigates backward one full set of rows.

  • removeRowWithKey: Tries to find a row using the serialized string representation of the row key passed as a parameter. If found, the row is removed.

  • setCurrentRowWithKey: Tries to find a row using the serialized string representation of the row key passed as a parameter. If found, that row becomes the current row.

  • setCurrentRowWithKeyValue: Tries to find a row using the primary key attribute value passed as a parameter. If found, that row becomes the current row.

  • commit: Persists to the database all changes that are made in the current transaction. (Only available for stateful bean-managed session facades that contain transactional methods)

  • rollback: Reverts all changes made within the context of the current transaction. (Only available for stateful bean-managed session facades that contain transactional methods)

Note:

By default, JavaBeans components assume the rowIndex as the key. If you do not explicitly define a key, the index will be used.

The Data Controls panel is a direct representation of the DataControls.dcx file and any data control structure files that are associated with the data control. By editing the files, you can change the elements displayed in the panel. Whenever changes are made to the services on which a data control is based, the data control incorporates those changes.

2.3 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 a data control 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 object is represented by a specific icon. Table 2-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 2-1 Data Control Icons and Object Hierarchy

Icon Name Description Used to Create...

Data control icon.

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.

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

Accessor return icon.

Accessor Returned Collection

Represents an object returned by a bean-style accessor method on the business service. For example, if when you created a session bean, you chose to also create accessor methods for each of the Java entities under the session bean, then an accessor returned collection is displayed for each of those entities.

If an entity contains a relationship to another entity (for example, a foreign key), then a child accessor returned collection is shown for that entity. In Oracle ADF, the relationship between parent and child entities is called a master-detail relationship.

The children under a collection may be attributes of the elements that make up the collection, operations on the entire collection, or operations on the row for each element in the collection.

For collections: forms, tables, trees, range navigation components, and master-detail widgets.

For single objects: forms, master-detail widgets, and selection lists.

For more information about creating forms, and navigation components, see Chapter 4, "Creating a Basic Databound Page."

For more information about creating tables, see Chapter 5, "Creating ADF Databound Tables."

For information about creating trees and other master-detail UI components, see Chapter 6, "Displaying Master-Detail Data."

For information about creating lists, see Chapter 7, "Creating Databound Selection Lists."

Attribute icon.

Attribute

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.

This icon is used in the Data Controls panel, but not in the overview editor for the DataControls.dcx file.

Label, text field, date and selection list components.

For information about creating text fields, see Section 4.2, "Using Attributes to Create Text Fields."

Method icon

Method

Represents a method that may accept parameters, perform some business logic, and optionally return a single value, a structure, or a collection of a single value and a structure.

Command components.

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

For information about creating command components from methods, see Section 4.6, "Creating a Form to Edit an Existing Record."

For information about creating parameterized forms, see Section 4.5, "Creating a Form Using a Method That Takes Parameters."

Method return icon.

Method Return

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

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.

For single values: text fields and selection lists.

For collections: forms, tables, trees, and range navigation components.

When a single-value method return is dropped, code to invoke the method is not automatically generated. You have to also create an invoke action as an executable, or drop the corresponding method as a button to invoke the method.

Data control operation icon.

Operation

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. The operations that are children of a particular collection or method return operate on those objects only.

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

This icon is used in the Data Controls panel, but not in the overview editor for the DataControls.dcx file.

Command components such as buttons or links.

For information about creating command components from operations, see Section 4.4, "Incorporating Range Navigation into Forms."

Parameter icon.

Parameter

Represents a parameter value that is declared by the method or operation under which it appears. Parameters appear in the Parameters node under a method or operation.

This icon is used in the Data Controls panel, but not in the overview editor for the DataControls.dcx file.

Label, text, and selection list components.

Named criteria icon

Named criteria

Represents a query from which you can create a user search form.

An All Queriable Attributes criteria is generated automatically for each accessor collection. This criteria can be used to create a search form where it is possible for the user to query based on any queriable attribute in the collection.

You can create custom view criteria and add them to the Data Controls panel. See Section 3.6, "Filtering Result Sets with Named Criteria".

This icon is used in the Data Controls panel, but not in the overview editor for the DataControls.dcx file.

Search forms.

For information on creating search forms, see Chapter 8, "Creating Databound Search Forms."


2.3.1 How to Use the Data Controls Panel

JDeveloper provides you with a predefined set of UI components from which to choose for each data control item you drop.

To use the Data Controls panel to create UI components:

  1. 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 2-1.

  2. 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.

    Figure 2-6 shows the context menu displayed when an accessor returned collection from the Data Controls panel is dropped on a page.

    Figure 2-6 Data Controls Panel Context Menu

    Menu of components to be dropped on a page

    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.

    The resulting UI component appears in the JDeveloper visual editor, as shown in Figure 2-7.

    Figure 2-7 Databound UI Component: ADF Table

    Table component in the JSF page visual editor

Tip:

Instead of creating automatically bound UI components using the Data Controls panel, you can create your UI first and then bind the components to the ADF Model layer. For more information, see the "Using Simple UI First Development" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

2.3.2 What Happens When You Use the Data Controls Panel to Create UI Components

When a web application is built using the Data Controls panel, JDeveloper does the following:

  • 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.

    DataBindings.cpx files define the binding context (a container object that holds a list of available data controls and data binding objects) for the application. Each DataBindings.cpx file maps individual pages to the binding definitions in the page definition file and registers the data controls used by those pages. Figure 2-8 shows a DataBindings.cpx file in the overview editor of JDeveloper.

    Figure 2-8 DataBindings.cpx File in the Overview Editor

    DataBindings.cpx for the Summit demo

    Example 2-3 shows the code from the corresponding XML file.

    Example 2-3 DataBindings.cpx File

    <?xml version="1.0" encoding="UTF-8" ?>
    <Application xmlns="http://xmlns.oracle.com/adfm/application"
                 version="11.1.2.59.53" id="DataBindings"
                 SeparateXMLFiles="false" Package="view" ClientType="Generic">
      <pageMap>
        <page path="/ViewCustomerOrders.jspx" 
              usageId="view_ViewCustomerOrdersPageDef"/>
        <page path="/editOrderItems.jspx" usageId="view_editOrderItemsPageDef"/>
        <page path="/CreateOrder.jspx" usageId="view_CreateOrderPageDef"/>
        <page path="PageFlow#addOrd" usageId="view_adfc_config___addOrdPageDef"/>
        <page  path="/WEB-INF/create-order-task-flow-definition.xml
                    #create-order-task-flow-definition@Create"
               usageId="view_adfc_config___CreatePageDef"/>
        <page path="/EditOrder.jspx" usageId="view_EditOrderPageDef"/>
        <page path="/login.jspx" usageId="view_loginPageDef"/>
        <page path="/viewCust.jspx" usageId="view_viewCustPageDef"/>
      </pageMap>
      <pageDefinitionUsages>
        <page id="view_ViewCustomerOrdersPageDef"
              path="view.pageDefs.ViewCustomerOrdersPageDef"/>
        <page id="view_editOrderItemsPageDef"
              path="view.pageDefs.editOrderItemsPageDef"/>
        <page id="view_CreateOrderPageDef" path="view.pageDefs.CreateOrderPageDef"/>
        <page id="view_adfc_config___CreatePageDef" 
              path="view.pageDefs.adfc_config___CreatePageDef"/>
        <page id="view_adfc_config___addOrdPageDef" 
              path="view.pageDefs.adfc_config___addOrdPageDef"/>
        <page id="view_EditOrderPageDef" path="view.pageDefs.EditOrderPageDef"/>
        <page id="view_loginPageDef" path="viewcontroller.pageDefs.loginPageDef"/>
        <page id="view_viewCustPageDef"
              path="viewcontroller.pageDefs.viewCustPageDef"/>
      </pageDefinitionUsages>
      <dataControlUsages>
        <dc id="OrdersSessionEJBLocal" path="model.OrdersSessionEJBLocal"/>
      </dataControlUsages>
    </Application>
    

    For more information about the .cpx file, see the "Working with the DataBindings.cpx File" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

  • Creates the adfm.xml file in the META-INF directory. This file creates a registry for the DataBindings.cpx file, and is used by the applications metadata layer to allow customization and personalization of the application. Example 2-4 shows an example of an adfm.xml file.

    Example 2-4 adfm.xml File

    <?xml version="1.0" encoding="UTF-8" ?>
    <MetadataDirectory xmlns="http://xmlns.oracle.com/adfm/metainf"
                       version="11.1.1.0.0">
      <DataBindingRegistry path="view/DataBindings.cpx"/>
    </MetadataDirectory>
    
  • For web applications, registers the ADF binding filter in the web.xml file.

    The ADF binding filter preprocesses any HTTP requests that may require access to the binding context. For more information about the filter, see the "Configuring the ADF Binding Filter" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

  • Adds the following libraries to the project:

    • ADF Model Runtime

    • ADF Model Generic Runtime

  • 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.

    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. Figure 2-9 shows a page definition file in the overview editor of JDeveloper.

    Figure 2-9 Page Definition File

    Overview editor for a page definition file
  • Configures the page definition file, which includes adding definitions of the binding objects referenced by the page. Example 2-5 shows the corresponding XML for a page definition.

    Example 2-5 Page Definition File

    <?xml version="1.0" encoding="UTF-8" ?>
    <pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel" version="11.1.2.59.53" id="CreateOrderPageDef"
                           Package="view.pageDefs">
      <parameters/>
      <executables>
        <variableIterator id="variables"/>
        <iterator Binds="root" RangeSize="25" DataControl="OrdersSessionEJBLocal"
                               id="OrdersSessionEJBLocalIterator"/>
        <accessorIterator MasterBinding="OrdersSessionEJBLocalIterator"
                          Binds="customerFindAll" RangeSize="25"
                          DataControl="OrdersSessionEJBLocal"
                          BeanClass="model.Customer" id="customerFindAllIterator"/>
        <accessorIterator MasterBinding="customerFindAllIterator" 
                          Binds="SOrdList" RangeSize="25"
                          DataControl="OrdersSessionEJBLocal" 
                          BeanClass="model.Ord" id="SOrdListIterator"/>
        <iterator Binds="root" RangeSize="25" DataControl="OrdersSessionEJBLocal"
                  id="OrdersSessionEJBLocalIterator1"/>
        <accessorIterator MasterBinding="OrdersSessionEJBLocalIterator1"
                          Binds="empFindAll" RangeSize="-1"
                          DataControl="OrdersSessionEJBLocal" 
                          BeanClass="model.Emp" id="empFindAllIterator"/>
      </executables>
      <bindings>
        <attributeValues IterBinding="SOrdListIterator" id="id">
          <AttrNames>
            <Item Value="id"/>
          </AttrNames>
        </attributeValues>
        <attributeValues IterBinding="SOrdListIterator" id="dateOrdered">
          <AttrNames>
            <Item Value="dateOrdered"/>
          </AttrNames>
        </attributeValues>
        <attributeValues IterBinding="SOrdListIterator" id="dateShipped">
          <AttrNames>
            <Item Value="dateShipped"/>
          </AttrNames>
        </attributeValues>
        <attributeValues IterBinding="SOrdListIterator" id="total">
          <AttrNames>
            <Item Value="total"/>
          </AttrNames>
        </attributeValues>
        <button IterBinding="SOrdListIterator" id="orderFilled" 
                DTSupportsMRU="false" StaticList="true">
          <AttrNames>
            <Item Value="orderFilled"/>
          </AttrNames>
          <ValueList>
            <Item Value="Y"/>
            <Item Value="N"/>
          </ValueList>
        </button>
        <list IterBinding="SOrdListIterator" id="paymentType" 
              DTSupportsMRU="true" StaticList="true">
          <AttrNames>
            <Item Value="paymentType"/>
          </AttrNames>
          <ValueList>
            <Item Value="CASH"/>
            <Item Value="CREDIT"/>
          </ValueList>
        </list>
        <list IterBinding="SOrdListIterator" id="salesRepId" 
              DTSupportsMRU="true" StaticList="false"
              ListIter="empFindAllIterator">
          <AttrNames>
            <Item Value="salesRepId"/>
          </AttrNames>
          <ListAttrNames>
            <Item Value="id"/>
          </ListAttrNames>
          <ListDisplayAttrNames>
            <Item Value="firstName"/>
            <Item Value="lastName"/>
          </ListDisplayAttrNames>
        </list>
        
        <methodAction IterBinding="customerFindAllIterator" id="addOrd"
                      RequiresUpdateModel="true"
                      Action="invokeMethod" MethodName="addOrd"
                      IsViewObjectMethod="false"
                      DataControl="OrdersSessionEJBLocal"
                      InstanceName="bindings.customerFindAllIterator.
                                    currentRow.dataProvider"
                      IsLocalObjectReference="true"
                      ReturnName="data.OrdersSessionEJBLocal.methodResults.
                                  addOrd_addOrd_addOrd_result">
          <NamedData NDName="order"
                     NDValue="#{bindings.SOrdListIterator.currentRow.dataProvider}"
                     NDType="model.Ord"/>
        </methodAction>   
        <methodAction id="mergeCustomer" RequiresUpdateModel="true"
                      Action="invokeMethod" MethodName="mergeCustomer"
                      IsViewObjectMethod="false"
                      DataControl="OrdersSessionEJBLocal"
                      InstanceName="data.OrdersSessionEJBLocal.dataProvider" 
                      ReturnName="data.OrdersSessionEJBLocal.methodResults.
                                  mergeCustomer_OrdersSessionEJBLocal_
                                  dataProvider_mergeCustomer_result">
          <NamedData NDName="customer"
                     NDValue="#{bindings.customerFindAllIterator.currentRow.
                              dataProvider}"
                     NDType="model.Customer"/>
        </methodAction>
      </bindings>
    </pageDefinition>
    

    For more information about the page definition file, see the "Working with Page Definition Files" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

  • Adds prebuilt components to the view page.

    These prebuilt components include ADF data bindings that reference the binding objects in the page definition file. Example 2-6 shows JSF page code for components that have been bound using ADF Model data binding.

    Example 2-6 JSF Page Code Fragment with ADF Model Data Binding

    .
    .
    .
    <af:table value="#{bindings.Ord.collectionModel}" var="row"
              rows="#{bindings.Ord.rangeSize}"
              emptyText="#{bindings.Ord.viewable ? 'No data to display.' : 
                           'Access Denied.'}"
              fetchSize="#{bindings.Ord.rangeSize}" rowBandingInterval="0"
              selectedRowKeys="#{bindings.Ord.collectionModel.selectedRow}"
              selectionListener="#{bindings.Ord.collectionModel.makeCurrent}"
              rowSelection="single" id="t1">
        <af:column sortProperty="#{bindings.Ord.hints.dateOrdered.name}"
                   sortable="false"
                   headerText="#{bindings.Ord.hints.dateOrdered.label}" id="c1">
            <af:outputText value="#{row.dateOrdered}" id="ot1">
                <af:convertDateTime
                     pattern="#{bindings.Ord.hints.dateOrdered.format}"/>
            </af:outputText>
        </af:column>
        <af:column sortProperty="#{bindings.Ord.hints.dateShipped.name}"
                   sortable="false"
                   headerText="#{bindings.Ord.hints.dateShipped.label}" id="c2">
            <af:outputText value="#{row.dateShipped}" id="ot2">
                <af:convertDateTime
                      pattern="#{bindings.Ord.hints.dateShipped.format}"/>
            </af:outputText>
        </af:column>
        <af:column sortProperty="#{bindings.Ord.hints.id.name}" sortable="false"
                   headerText="#{bindings.Ord.hints.id.label}" id="c3">
            <af:outputText value="#{row.id}" id="ot3"/>
        </af:column>
    .
    .
    .
    
  • For applications that use ADF Faces, adds all the files, and configuration elements required by ADF Faces components. For more information, see the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

2.3.3 What Happens at Runtime

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 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 ADF binding context from the DataControls.dcx, DataBindings.cpx, and page definition files, as shown in Figure 2-10. The DataControls.dcx file defines the data controls available to the application at design time, while 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, or in the case of a Java Swing application, the Java class. The page definition files define the binding objects used by the application pages. There is one page definition file for each page.

Figure 2-10 ADF Binding File Runtime Usage

dcx, cpx, page def make up binding context

The binding context does not contain real live instances of these objects. Instead, the map first contains references that become data control or binding container objects on demand. When the object (such as the page definition) is released from the application (such as 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 more information, see the "Understanding the Fusion Page Lifecycle" chapter of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

2.3.4 What You May Need to Know About Iterator Result Caching

When a data control modifies a collection, the data control must instantiate a new instance of the collection in order for the ADF Model layer to understand that it has been modified. In other words, although some action in the client may change the collection, that change will not be reflected in the UI unless a new instance of the collection is created. However, for performance reasons, accessor and method iterators cache their results set (by default, the cacheResults attribute on the iterator is set to true). This setting means that the iterator is refreshed and a new instance of the collection is created only when the page is first rendered. The iterator is not refreshed when the page is revisited, for example, if the page is refreshed using partial page rendering, or if the user navigates back to the page.

For example, say you want to allow sorting on a table on your page. Because you want the page to refresh after the sort, you add code to the listener for the sort event that will refresh the table using partial page rendering (for more information, see the "Rerendering Partial Page Content" chapter of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework). Because the instance of the collection for the table has already been instantiated and is cached, the accessor iterator will not reexecute, which means that a new instance of the collection with the new sort order will not be created, so the sort order on the page will remain the same.

To work around this issue, you can either configure the iterator so that it does not cache the results, or you can place a button on the page that can be used to reexecute the iterator when the page is refreshed. If your page does not have a button whose action attribute can be bound to a method, then you can use an invokeAction executable that will be invoked whenever the page is refreshed.

Note:

If your page uses the navigation operations to navigate through the collection, do not set CacheResults to false, as that navigation will no longer work. You must use a button to reexecute the iterator. For more information about the navigation operations, see Section 4.4, "Incorporating Range Navigation into Forms."

Performance Tip:

If you set an iterator to not cache its result set, and that result set is a collection that may return a large number of rows, performance will be negatively affected. For large result sets, you should use an invokeAction.

To set an iterator to not cache its result set:

  1. Open the page definition file, and in the Structure window, select the iterator whose results should not be cached.

  2. In the Property Inspector, expand the Advanced section and set CacheResults to false.

To use a button to reexecute the iterator:

  1. From the ADF Faces page of the Component Palette, drag and drop a Button onto the page.

  2. In the Structure window, right click the button and in the context menu, choose Bind to ADF Control.

  3. In the Bind to ADF Control dialog, expand the accessor associated with the iterator to reexecute, expand that accessor's Operations node, and select Execute.

To use an invokeAction to reexecute the iterator:

  1. Open the page definition file, and in the Structure window, right-click executables and choose Insert inside executables > invokeAction.

  2. In the Insert invokeAction dialog, set id to a unique name. Use the Binds dropdown list to select the iterator to be reexecuted.

  3. With the newly created invokeAction still selected, in the Property Inspector, set Refresh to prepareModel.

    This setting will cause the accessor method to be invoked during the Prepare Model phase. This refreshes the binding container.

  4. Set RefreshCondition to an EL expression that will cause the refresh to happen only if any value has actually changed. If this condition is not set, the invokeAction will be called twice.

    For more information about the page lifecycle phases and using the refresh and refreshCondition attributes, see "About the JSF and ADF Page Lifecycles" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

2.3.5 What You May Need to Know About Configuring Validation

In addition to being able to set validation on attributes at the data control level, you can also set validation on the attribute bindings in a page definition file. When a user edits or enters data in a field for an attribute for which validation has been defined, and submits the form, the bound data is validated against the configured rules and conditions. If validation fails, the application displays an error message.

In most cases, setting validation at the data control level is preferable to setting validation at the page level. Any validation rules that you set on a data control are applied in all of the UI components that are created from the data control.

For information and procedures on setting validation on data controls, see Section 3.5, "Defining Validation Rules on Attributes Declaratively".

For information and procedures on setting validation on individual UI components, see the "Using Validation in the ADF Model Layer" chapter of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

When you set validation, you can define the error message that will be displayed. By default, these messages are displayed in a client dialog. You can configure these messages to display inline instead. For more information, see the "Displaying Hints and Error Messages for Validation and Conversion" section of the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework.

You can also change the way messages are handled by creating your own error handling class. For more information, see the "Customizing Error Handling" section of the Oracle Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework.

2.3.6 What You May Need to Know About Custom Session Bean Accessor Methods

By default, when you drag an accessor returned collection from a session bean data control onto a page, the result is a paginated collection. In this case, the built-in session bean's queryByRange() method will be referenced from the bindings (instead of the corresponding getBeanFindAll() method in the session bean). If you have custom code for a getBeanFindAll(), getBeanFindAllSize(), or getBeanFindAll(x,y) method on a bean that you want to make sure is used at runtime, you need to remove the data control's DataControlHandler attribute. You can remove the DataControlHandler attribute in the source editor for the DataControls.dcx file. However, when you remove that attribute, the built-in support for named queries and pagination is also disabled.