Skip Headers
Oracle® Application Development Framework Developer's Guide
10g Release 3 (10.1.3)
B25386-01
  Go To Documentation Library
Home
Go To Product List
Solution Area
Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
Next
Next
 

5.5 Working with Page Definition Files

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

5.5.1 How to Create a Page Definition File

The first time you use the Data Control Palette to create a databound component, 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. You can change the location of the page definition files on the ADFm Settings page of the project properties.

JDeveloper names the page definition files using the following convention:

<pageName>PageDef.xml

where <pageName> is the name of the JSF page. For example, if the JSF page is named SRList.jsp, the default page definition filename is SRListPageDef.xml.


Caution:

The DataBindings.cpx file maps JSF pages to their corresponding page definition files. If you change the name of a page definition file or a JSF page, JDeveloper does not automatically refactor the DataBindings.cpx file. You must manually update the page mapping in the DataBindings.cpx file to reflect the new page name.

5.5.2 What Happens When You Create a Page Definition File

Example 5-7 shows a sample page definition file that was created for the SRList page in the SRDemo application. Notice that the page definition file groups the binding object definitions under the following wrapper elements:

Each wrapper element contains specific types of binding object definitions. The id attribute of each binding object definition specifies the name of the binding object. Each binding object name must be unique within the page definition file. In Section 5.6, "Using ADF Databinding EL Expressions", you will see how the ADF databinding EL expressions reference the binding object names.

Example 5-7 Page Definition File

<?xml version="1.0" encoding="UTF-8" ?>
<pageDefinition xmlns="http://xmlns.oracle.com/adfm/uimodel"
                version="10.1.3.35.65" id="SRListPageDef"
                Package="oracle.srdemo.view.pageDefs">
  <parameters/>
  <executables>
    <methodIterator id="findServiceRequestsIter"
                    Binds="findServiceRequests.result"
                    DataControl="SRPublicFacade" RangeSize="10"
                    BeanClass="oracle.srdemo.model.entities.ServiceRequest"/>
    <invokeAction Binds="findServiceRequests" id="tableRefresh"
                  Refresh="ifNeeded"
                  RefreshCondition="${(userState.refresh) and
                        (!adfFacesContext.postback)}"/>                    
    <variableIterator id="variables">
      <variable Type="java.lang.String" Name="setCurrentRowWithKey_rowKey"
                IsQueriable="false"/>
    </variableIterator>
  </executables>
  <bindings>
    <methodAction id="findServiceRequests"
                  InstanceName="SRPublicFacade.dataProvider"
                  DataControl="SRPublicFacade"
                  MethodName="findServiceRequests" RequiresUpdateModel="true"
                  Action="999"
                  ReturnName="SRPublicFacade.methodResults.
                          SRPublicFacade_dataProvider_findServiceRequests_result">
      <NamedData NDName="userIdParam" NDValue="#{userInfo.userId}"
                 NDType="java.lang.Integer"/>
      <NamedData NDName="statusParam" NDValue="#{userState.listMode}"
                 NDType="java.lang.String"/>
    </methodAction>
    <table id="findServiceRequests1" IterBinding="findServiceRequestsIter">
      <AttrNames>
        <Item Value="assignedDate"/>
        <Item Value="problemDescription"/>
        <Item Value="requestDate"/>
        <Item Value="status"/>
        <Item Value="svrId"/>
      </AttrNames>
    </table>
    <action id="setCurrentRowWithKey" IterBinding="findServiceRequestsIter"
            InstanceName="SRPublicFacade.dataProvider"
            DataControl="SRPublicFacade" RequiresUpdateModel="false"
            Action="96">
      <NamedData NDName="rowKey" NDValue="${row.rowKeyStr}"
                 NDType="java.lang.String"/>
    </action>
  </bindings>
</pageDefinition>

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.7, "<pageName>PageDef.xml".

5.5.2.1 About the Bindings in the parameters Element

The parameters element of the page definition file defines the parameters for the page. Parameter binding objects are argument values used by:

The parameter binding objects declare the parameters that the page evaluates at the beginning of a request (in the Prepare Model phase of the ADF lifecycle). In a web application, the page parameters are evaluated once during the Prepare Model phase. (For more information about the ADF lifecycle, see Section 6.2.2.4, "The JSF and ADF Lifecycles".) You can define the value of a parameter in the page definition file using static values, binding expressions, or EL expressions that assign a static value.

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

Example 5-8 The parameters Element of a Page Definition File

<parameters>
  <parameter id="filedBy"
               value="${bindings.userId}"/>
  <parameter id="status"
               value="${param.status != null ?  param.status : 'Open'}"/>
</parameters>

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


Tip:

By default, JDeveloper uses a dollar sign ($) as the prefix for EL expressions that appear in the page definition file. However, you can use the hash sign (#) prefix as well.

For more information about passing parameters to methods, see Chapter 10, "Creating More Complex Pages".

5.5.2.2 About Bindings in the executables Element

The executables element of the page definition file defines the following types of binding objects:

  • Iterator objects: Iterate over the data objects returned by methods and accessors and expose the current object and range state to the bindings. The range is the current set of objects returned by the iterator. For example, if a method returns a collection of user objects, the range may be the first ten user objects in the collection. Iterator bindings bind to a RowSetIterator object that iterates over the data objects. A RowSetIterator object manages the current object (also known as the row currency) and current range information. There is one iterator for each method return and accessor return used in the page. Most of the other bindings on the page must refer to an iterator.

  • invokeAction objects: Used to invoke method actions.

The executables element shown in Example 5-9, defines two iterators and an invokeAction binding object.

Example 5-9 The executables Element in a Page Definition File

  <executables>
    <methodIterator id="findServiceRequestsIter"
                    Binds="findServiceRequests.result"
                    DataControl="SRPublicFacade" RangeSize="10"
                    BeanClass="oracle.srdemo.model.entities.ServiceRequest"/>
    <invokeAction Binds="findServiceRequests" id="tableRefresh"
                  Refresh="ifNeeded"
                  RefreshCondition="${(userState.refresh) and
                                     (!adfFacesContext.postback)}"/>                    
    <variableIterator id="variables">
      <variable Type="java.lang.String" Name="setCurrentRowWithKey_rowKey"
                IsQueriable="false"/>
    </variableIterator>
  </executables>

  <bindings>
    <methodAction id="findServiceRequests"
                  InstanceName="SRPublicFacade.dataProvider"
                  DataControl="SRPublicFacade"
                  MethodName="findServiceRequests" RequiresUpdateModel="true"
                  Action="999"
                  ReturnName="SRPublicFacade.methodResults.
                          SRPublicFacade_dataProvider_findServiceRequests_result">
      <NamedData NDName="userIdParam" NDValue="#{userInfo.userId}"
                 NDType="java.lang.Integer"/>
      <NamedData NDName="statusParam" NDValue="#{userState.listMode}"
                 NDType="java.lang.String"/>
    </methodAction>

    <table id="findServiceRequests1" IterBinding="findServiceRequestsIter">
    ...
  </bindings>

In the example, the executables element contains two types of iterators: method and variable.

A method iterator iterates the results returned from a method. For example, the findServiceRequestIter method iterator was created by dragging the findServiceRequest method return from the Data Control Palette onto the page. It iterates over the collection returned by the findServiceRequest method, which is defined in the bind attribute of the methodIterator element. The RangeSize attribute defines the number of rows to return at one time. A RangeSize value of -1 causes the iterator to return all the rows. A method iterator is always related to a methodAction defined in the bindings element. The methodAction encapsulates the details about how to invoke the method and what parameters (if any) the method is expecting. In the example, the method iterator is related to the findServiceRequests method action. The NamedData elements define the parameters to be passed to the method. The table binding object defined in the bindings element references the findServiceRequestIter iterator in the IterBinding attribute to populate the data in the table.The invokeAction object, also in the executables element, invokes the findServiceRequests method. The Refresh attribute determines when in the ADF lifecycle the method is executed, while the RefreshCondition attribute provides a condition for invoking the action. (For more information about the Refresh and RefreshCondition attributes, see Section A.7, "<pageName>PageDef.xml". For examples of using the Refresh and RefreshCondition attributes, see Section 10.8, "Creating Search Pages".)

A variable iterator iterates the variables created within the binding container. These variables are local to the binding container and exist only while the binding container object exists. When you use a data control method or 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 binding container variables. In the example, there is one variable iterator that iterates over the variable called setCurrentRowWithKey_rowKey, which is a parameter required by the setCurrentRowWithKey operation.

If an accessor return from the Data Control Palette had been dropped on the page, the executables element would contain an accessor iterator. An accessor iterator iterates over detail objects returned by accessor methods. Accessor iterators are always related to a master iterator, which is the method iterator for the parent object. The accessor iterator returns the detail objects related to the current object in the master (or method) iterator. For more information about master-detail objects and iterators, see Chapter 8, "Working with Master-Detail Relationships".

At runtime, the bindings in the executables element are executed in the order in which they appear in the page definition file. Before they are executed, the runtime evaluates the Refresh and RefreshCondition attributes specified in the iterator. The Refresh and RefreshCondition attributes determine when or whether the executable should be invoked.

5.5.2.3 About the Bindings in the bindings Element

The bindings element of the page definition file defines the following types of binding objects:

  • Value binding objects: Display data in the UI by referencing an iterator. Each discrete UI component on a page is bound to a value binding object. Value binding objects include:

    • Table binding objects, which bind an entire table to a data collection

    • List binding objects, which binds the list items to a data collection or object

    • Tree binding objects, which bind the root node of a tree to a data collection

    • Attribute binding objects, which bind text fields to a specific attribute in a data collection or object

    Some composite components, such as tables, selection lists, and trees are bound to a single value binding object, which references a single iterator to populate the data. However, each component in a form is individually bound to a value binding object.

  • methodAction binding objects: Encapsulate the details about how to invoke a method and what parameters (if any) the method is expecting. There is one method action binding for each method iterator used in the page.

  • Action binding objects: Bind an action component, such as a button or link, to a data control operation or method. In an action binding, a component's actionListener is bound to the operations that perform the required action. Operations for action bindings can be built-in ones supplied by the binding objects (like Create, Delete, Next, Previous, Save, Commit) or custom methods from your data control implementation.

In the bindings element shown in Example 5-10, there is one methodAction binding called findServiceRequest, one value binding for a table called findServiceRequest1 and one action binding called setCurrentRowWithKey.

Because the findServiceRequests method used in the sample accepts parameters, the method action binding contains NamedData elements that define the parameters expected by this method. For more information about passing parameters to methods, see Chapter 10, "Creating More Complex Pages".

In the table binding object, the IterBinding attribute references the appropriate iterator that iterates over the data collection that populates that value. Notice that a table is handled by a single binding object that references the iterator once for all the attributes displayed in the table. This means that the table can only display data from a single data collection. However, for container components like forms, each individual attribute has a binding object, which references an iterator. Forms, unlike tables, can contain attributes from multiple data collections. The AttrNames element defines all the attribute values returned by the iterator.

The action binding is bound to a command link that returns a specific service request when the user clicks the link. It references the findServiceRequestsIter iterator and passes it the current row key as a parameter, which is defined in the namedData element.

Example 5-10 The bindings Element of a Page Definition File

<bindings>
  <methodAction id="findServiceRequests"
                InstanceName="SRPublicFacade.dataProvider"
                DataControl="SRPublicFacade"
                MethodName="findServiceRequests" RequiresUpdateModel="true"
                Action="999"
                ReturnName="SRPublicFacade.methodResults.
                               SRPublicFacade_dataProvider_findServiceRequests_
                               result">
    <NamedData NDName="userIdParam" NDValue="#{userInfo.userId}"
               NDType="java.lang.Integer"/>
    <NamedData NDName="statusParam" NDValue="#{userState.listMode}"
               NDType="java.lang.String"/>
  </methodAction>
  <table id="findServiceRequests1" IterBinding="findServiceRequestsIter">
    <AttrNames>
      <Item Value="assignedDate"/>
      <Item Value="problemDescription"/>
      <Item Value="requestDate"/>
      <Item Value="status"/>
      <Item Value="svrId"/>
    </AttrNames>
  </table>
  <action id="setCurrentRowWithKey" IterBinding="findServiceRequestsIter"
          InstanceName="SRPublicFacade.dataProvider"
          DataControl="SRPublicFacade" RequiresUpdateModel="false"
          Action="96">
    <NamedData NDName="rowKey" NDValue="${row.rowKeyStr}"
               NDType="java.lang.String"/>
  </action>
</bindings>

5.5.3 What Happens at Runtime

At runtime, the ADF page lifecycle passes the page URL to the ADF binding context, which matches the URL to a page definition file using the information in the DataBindings.cpx file. Then, the binding context instantiates the binding container, which is the runtime instance object that contains all of the binding objects defined in the page definition file. All the data that is displayed by a page's UI components is provided by the binding objects in the binding container. The ADF databinding expressions in a page are evaluated at runtime and are replaced by values supplied by the binding objects when the page is rendered.

5.5.4 What You May Need to Know About Binding Container Scope

By default, the binding container and the binding objects it contains are defined in session scope. The values referred to by binding objects are managed by the data control and RowSetIterator objects, both of which also have session scope. By default, the RowSetIterator state and the data caches are maintained between requests. However, the values that binding objects refer to are only valid during a request in which that binding container has been prepared by the ADF lifecycle.