Cross Column

Showing posts with label Binding Container. Show all posts
Showing posts with label Binding Container. Show all posts

Monday, May 3, 2010

Oracle ADF BindingContext and BindingContainer

The Oracle ADF binding context is a runtime map (accessible through the EL expression #{data}) of all data controls and page definitions within the application. 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. The ADF lifecycle creates the binding context from the application module, DataBindings.cpx, and page definition files.

In Oracle ADF, 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. For example, to access the collectionModel of binding object named MyShoppingCart , you use the EL expression:
  #{bindings.MyShoppingCart.collectionModel}

BindingContext

The binding context lives in the HttpSession for each end user. It holds references to lightweight application module data control objects that manage acquiring an application module instance from the pool during the request (when the data control is accessed) and releasing it to the pool at the end of each request. The data control holds a reference to the ADF session cookie that identifies the user session. The binding context also holds references to binding containers. The binding context might contain many data controls and many binding containers.

There are three options to access the binding context at runtime by Fusion Web Applications:
  1. BindingContext.getCurrent()
  2. BindingUtils.getBindingContext()
  3. JsfUtils.resolveExpression("#{data}")
For option 1 and 2, they are implemented in the same way internally:
  import oracle.adf.model.BindingContext;

  (BindingContext)ADFContext.getCurrent().getSessionScope().get("data");
However, option 3 is different and resolveExpression() is defined to be:
public static Object resolveExpression(String expression) {
FacesContext facesContext = getFacesContext();
Application app = facesContext.getApplication();
ExpressionFactory elFactory = app.getExpressionFactory();
ELContext elContext = facesContext.getELContext();
ValueExpression valueExp =
elFactory.createValueExpression(elContext, expression,
                     Object.class);
return valueExp.getValue(elContext);
}

As you can see it, the third approach is more expensive because it involves extra expression parsing and syntactic validation of the expression.

BindingContext is an object that implements the Map interface and exposes generic methods to access the binding layer. For example, to find a data control, you could use the findDataControl()method on BindingContext
  findDataControl(dc_name)


BindingContainer

To access binding container, you first retrieve binding context as described above; then you use binding context's getCurrentBindingsEntry method to retrieve binding container object:
  import oracle.binding.BindingContainer;

  BindingContainer bc = bindingContext.getCurrentBindingsEntry();
Internally, getCurrentBindingsEntry() is implemented as follows:
  (BindingContainer)ADFContext.getCurrent().getRequestScope().get("bindings");

If you use option 3 as described above, you can retrieve binding container in a more straightforward way (although it's still more expensive):
FacesContext facesContext = FacesContext.getCurrentInstance();
ExpressionFactory exp = facesContext.getApplication().getExpressionFactory();
DCBindingContainer bindingContainer =
(DCBindingContainer)exp.createValueExpression(facesContext.getELContext(),
"#{bindings}",DCBindingContainer.class).getValue(facesContext.getELContext());

Fusion application developers who prefer working with type-safe methods can cast the bindings instance (i.e., BindingContainer) to DCBindingContainer:

DCBindingContainer object exposes more methods than the its super class object BindingContainer. For example, you can access the application module's client interface from this DCBindingContainer by naming an ADF action binding or an ADF iterator binding as shown below:
// 1. Access the binding container
DCBindingContainer bc = (DCBindingContainer)getBindings();
// 2. Find a named action binding
JUCtrlActionBinding action =
(JUCtrlActionBinding)bc.findCtrlBinding("SomeActionBinding");
// 3. Get the data control from the iterator binding (or method binding)
DCDataControl dc = action.getDataControl();
// 4. Access the data control's application module data provider
ApplicationModule am = (ApplicationModule)dc.getDataProvider();
// 5. Cast the AM to call methods on the custom client interface
StoreServiceAM service = (StoreServiceAM)am;
// 6. Call a method on the client interface
service.doSomethingInteresting();

Final Words

In this article, we have demonstrated how bindings can be accessed via Java code. However, this should be done only as appropriate. In other words, use it when attribute or executable binding properties at JDeveloper's designtime are not able to declaratively meet the needs of the application.

References

  1. Oracle Fusion Developer Guide by Frank Nimphius and Lynn Munsinger
  2. Oracle Fusion Applications Developer's Guide 11g

Tuesday, November 24, 2009

Oracle ADF Model In Depth

Oracle ADF Model implements the two concepts in JSR-227 that enable decoupling the user interface technology from the business service implementation:

  • data controls
    • A data control abstracts the implementation of a business service, allowing the binding layer to access the data from all services in a consistent way.
    • At runtime, the ADF Model layer reads the information describing the data controls and bindings from appropriate XML files and implements the two-way connection between the user interface and the business service.
  • declarative bindings
    • Declarative bindings abstract the details of accessing data from data collections in a data control and of invoking its operations.
    • There are 3 basic kinds of declarative binding objects:
      • Iterator bindings -- to allow scrolling and paging through collections of data and drilling-down from summary to detail information
      • Value bindings -- to display data
      • Action bindings -- to invoke built-in or custom operations on data collections of a data control. They are represented as operations in the Data Controls panel.
The following figure shows how bindings connect UI components to data control collections and methods.

In the following sections, we will see what kind of metadata are needed at design time to bind UI components (or widgets) to their associated data collections or methods declaratively and what kind of objects are generated at runtime to support the gluing.

Design Time

When you begin adding content to your page, you typically use the Component Palette and Data Controls panel of JDeveloper. The Component Palette contains all the ADF Faces components needed to declaratively design your page. Once you have the basic layout components placed on the page, you can then drag and drop items from the Data Controls panel to create ADF Model databound UI components.

From the item (i.e., accessor or attribute) dragged over from the Data Controls panel, JDeveloper first compiles a list of compatible BindingsTypes. From this list, JDeveloper can then determine the set of Creators that are applicable to drop on the page. The user is then presented with this list (organized by BindingsType). When the user selects a Creator to use, the Creator builds the databound UI component (by producing a DOM subtree representing what will be inserted into the page).
For example, If you drop the PrincipalName attribute from the Data Controls panel as an Input Text w/Label widget, JDeveloper creates an inputText component. The following code shows the code generated on the JSF page when you drop the PrincipalName attribute as an Input Text w/Label widget. Notice that the value of the component is bound to the inputValue property of the PrincipalName binding.


           shortDesc="#{bindings.PrincipalName.hints.tooltip}" id="it1">


You can change any of these properties to suit your needs. Reference this appendix for the properties of the ADF bindings.

If you build your application using these databound UI components, JDeveloper will create the following metadata files for you:
  • Add a page definition file. The page definition file (pageNamePageDef.xml) defines the group of bindings supporting the UI components on a page.
  • Create a DataBindings.cpx file and addes an entry for the page. The DataBindings.cpx file acts as the table of contents to the data controls in use in this application.
  • Create the adfm.xml file. 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.

Runtime

At runtime, multiple objects (i.e., binding context, binding containers, and binding objects) are created in memory to hold binding information. The ADF binding context is a runtime map of all data controls and page definitions within the application. The binding context is the one object that lives in the HttpSession for each end user, accessible using the EL expression #{data}.

The group of bindings supporting the UI components on a page are described in a 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.

  • Binding Context
    • The binding context provides the data environment for your application. It contains all of the data controls and binding containers that your application can access.
    • The ADF lifecycle creates the ADF binding context from the application module, DataBindings.cpx, and page definition files. Binding context contains references that become data control or binding container objects on demand.
    • You can look up ApplicationModule from a managed bean using the BindingContext:
      BindingContext bc = BindingContext.getCurrent();
      DCDataControl dc = bc.findDataControl("AppModuleDataControl");
      ApplicationModule am = (ApplicationModule)dc.getDataProvider();
    • You can retrieve a ControlBinding named "producerMethod" via BindingContext in this way:
      DCBindingContainer bc = (DCBindingContainer)BindingContext.getCurrent().getCurrentBindingsEntry();
      JUCtrlActionBinding actionBnd =
      (JUCtrlActionBinding)bc.getControlBinding("producerMethod");
  • Binding Containers
    • A binding container holds value bindings and iterator bindings (or binding objects) for a page. It provides runtime access to all the ADF binding objects for a page.
At runtime, a web request for http://yourserver/yourapp/faces/some.jsp arrives from the client to the application server. The ADFBindingFilter (defined in web.xml) object looks for the ADF binding context in the HTTP session, and if it is not yet present, initializes it for the first time. If the appropriate binding container for the page has never been used before during the user's session, it is created. Also, if it is the first time an application module data control is referenced during the request, it acquires an instance of the application module from the application module pool. Then the control is forwarded to the page to be rendered. The UI components on the page access value bindings and iterator bindings in the page's binding container and render the formatted output to appear in the browser. Finally, the user sees the resulting page in the browser.

References

  1. Using Oracle ADF Model in a Fusion Web Application
  2. Understanding the Fusion Page Lifecycle
  3. Oracle Fusion Middleware Online Documentation Library 11g Release (11.1.1.2)
  4. Oracle ADF BindingContext and BindingContainer

© Travel for Life Guide. All Rights Reserved.

Analytical Insights on Health, Culture, and Security.