Monday, November 30, 2009

Managed Beans in Oracle Fusion Web Applications

In JDeveloper, it helps you create different types of applications using various templates. One of these templates is the Fusion Web Application (ADF) template, which provides the correctly configured set of projects you need to create a web application that uses ADF Faces for the view, ADF Controller for the controller, and ADF Business Components for business services. When you create an application using this template, JDeveloper automatically creates the JSF and ADF configuration files needed for the application.


Oracle ADF framework is a container in the sense that it contains and manages the lifecycle and configuration of application objects. In the ADF framework, you can declare how each of your application objects should be created, how they should be configured, and how they should be associated with each other.

Managed Beans

A managed bean - sometimes simply referred to as an MBean - is a type of JavaBean, created with dependency injection and registered with the application using various configuration files. Managed Beans are particularly used in the Java Management Extensions technology. But with Java EE 6, the specification provides for a more detailed meaning of a managed bean.

The MBean represents a resource running in the Java virtual machine, such as an application or a Java EE technical service (transactional monitor, JDBC driver, etc.). They can be used for getting and setting applications configuration (pull), for collecting statistics (pull) (e.g. performance, resources usage, problems) and notifying events (push) (e.g. faults, state changes).

Backing beans are managed beans that contain logic and properties for UI components on a JSF page. In a standard JSF application, managed beans are registered in the faces-config.xml configuration file.

Three characteristics of a managed bean:
  • Name — way to reference bean in JSF application
  • Class — fully qualified class name of bean
  • Scope — how long the bean will live (i.e., application, session, request)

The managed-bean element can contain zero or more managed-property elements (see example below), each corresponding to a property defined in the bean class. These elements are used to initialize the values of the bean properties. If you don’t want a particular property initialized with a value when the bean is instantiated, do not include a managed-property definition for it in your application configuration resource file. Read this article to learn how to use the managed-property element.

Dependency Injection

The key benefit of Dependency Injection (DI) is loose coupling. When applying DI, objects are given their dependencies at creation time by some external entity that coordinates each object in the system. In other words, dependencies are injected into objects. So, DI means an inversion of responsibility with regard to how an object obtains references to collaborating objects. With DI, your application objects are freed from the burden of fetching their own dependencies and are able to focus on their tasks, trusting that their dependencies will be available when needed.

JavaServer Faces Managed Bean Facility

In this article, it discusses JavaServer Faces Managed Bean Facility which is provided similarly in the ADF framework. In summary, it provides the following functionalities:

  • Control of instantiation (constructor) and setter based injection of managed objects
  • Control when objects are loaded (i.e., eager instantiation vs. lazy loading)
  • Dependency Handling
  • Lifecycle Support
  • Configuration Support

Managed Beans in Fusion Web Applications

The controller used in ADF framework is ADF Controller (ADFc). It is an extension to JSF page flow engine. It allows the definition of managed beans with additional memory scopes[5]:
  • Application scope
  • Session scope
  • Page flow scope
  • Request scope
  • Backing bean scope
  • View scope
In a Fusion web application, managed beans can be registered in:
  • faces-config.xml file
  • adfc-config.xml file
  • task flow definition file[6]
However, registering managed beans within the faces-config.xml file is not recommended in a Fusion web application. Managed beans accessed within the task flow definition must be registered in that task flow's definition file. As a general rule for Fusion web applications, a bean that may be used in more than one page or task flow, or one that is used by pages within the main unbounded task flow (adfc-config), should be registered in the adfc-config.xml configuration file. A managed bean that will be used only by a specific task flow should be registered in that task flow's definition file. For example, a managed bean named updateUserInfoBean is registered in adfc-config.xml below:
<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/controller" version="1.2">
 <view id="TestPage">
   <page>/TestPage.jspx</page>
 </view>
 <view id="Messages">
   <page>/ui/page/Messages.jspx</page>
 </view>
  <managed-bean>
    <managed-bean-name>updateUserInfoBean</managed-bean-name>
    <managed-bean-class>oracle.fodemo.storefront.account.view.managed.UpdateUserInfoBean</managed-bean-class>
    <managed-bean-scope>session</managed-bean-scope>
    <managed-property>
      <property-name>allItemsIteratorName</property-name>
      <value>AvailableCategoriesShuttleListIterator</value>
    </managed-property>
    <managed-property>
      <property-name>allItemsValueAttrName</property-name>
      <value>CategoryId</value>
    </managed-property>    <managed-property>
      <property-name>allItemsDisplayAttrName</property-name>
      <value>CategoryName</value>
    </managed-property>
    <managed-property>
      <property-name>allItemsDescriptionAttrName</property-name>
      <value>CategoryDescription</value>
    </managed-property>
    <managed-property>
      <property-name>selectedValuesIteratorName</property-name>
      <value>CustomerInterestsIterator</value>
    </managed-property>
    <managed-property>
      <property-name>selectedValuesValueAttrName</property-name>
      <value>CategoryId</value>
    </managed-property>
    <managed-property>
      <property-name>addressTable</property-name>
      <property-class>oracle.adf.view.rich.component.rich.data.RichTable</property-class>
      <value></value>
    </managed-property>
  </managed-bean>
</adfc-config>

You can also find another managed bean example in this article. Finally, in a Fusion web application, you should use managed beans to store logic that is related to the UI rendering only. All application data and processing should be handled by logic in the business layer of the application.

More Reading...


  1. Creating and Using Managed Beans (if you use ADF Faces components in a standard JSF application)
  2. Using a Managed Bean in a Fusion Web Application (if you use Oracle ADF Model data binding and ADF Controller)
  3. JavaServer Faces (JSF) Tutorial
  4. Backing Bean in JSF Tutorial
  5. Types of Memory Scopes in Fusion Web Application
  6. Oracle ADF Task Flow in a Nutshell
  7. Using a Managed Bean in a Fusion Web Application

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