Bean reference technique to enable Oracle Application Development Framework regions to make callbacks to their parent pages.Part 1
One of the core architecture patterns in Oracle Application Development Framework (Oracle ADF) that promotes modular software design is the ability to expose bounded task flows in regions on a page. For a region to make callbacks to the owning page or view at runtime, developers typically use one of the following techniques:
• Contextual events, the messaging channel of the Oracle ADF binding layer, which enables Oracle ADF regions to establish bidirectional communication with other regions as well as the owning page or view.
• The task flow parent action activity, which can be used to invoke a navigation case on a parent page or view. It’s a declarative option, however, that allows only navigation.
• Bean reference, a technique in which a managed bean of the parent page task flow is passed as reference to a bounded task flow exposed in a region. The bounded task flow uses this reference to invoke a method on the managed bean, thus calling back into the parent task flow.
Using contextual events, covered in two previous Oracle Magazine articles (see “Implement Contextual Events” and “Master and Commander”), is the most powerful technique for page-to-region and region-to-region interaction, and it also enables communication with nested regions. However, setting up contextual events is complex, and many developers balk at the unnecessary overhead for simple region communication use cases.
The bean reference technique explained in this article is easy to implement and well suited for many region communication use cases, making it an important part of the everyday toolbox of an Oracle ADF developer. This article explains how to configure and use a managed bean reference as a communication channel between a region and its parent page or view and includes a hands-on tutorial for you to walk through, using a provided sample application.
Note that for the rest of this article, the parent page task flow is referred to as the parent task flow. The page or page fragment (view) containing the region is referred to as the parent page.
As shown in Figure 1, the bean reference technique involves two managed beans. The first managed bean is defined in view scope of the parent task flow, and the other bean is defined in pageFlowScope of the bounded task flow that is exposed in the region.
Figure 1: Bean reference technique design-time architecture
The managed bean of the parent task flow is passed as a reference to an input parameter that is defined on the bounded task flow exposed through the region. The bounded task flow saves the bean reference in a variable of its pageFlowScope bean. Using the reference to the managed bean in the parent task flow, the bounded task flow can then invoke methods on the bean or pass information to the parent task flow.
To understand why this technique works, it is important to review bean scopes and lifecycles. A managed bean configured in view scope lives as long as the page from which it is referenced remains active. The lifecycle of a task flow exposed in a region starts during the rendering of the parent page (unless the activation property is set to deferred). The task flow is dismissed when the application navigates away from the parent page, at which time the bounded task flow managed bean also becomes available for garbage collection.
As a result, both managed beans in our bean reference design—the managed bean in view scope of the parent task flow and the managed bean in page flow scope of the bounded task flow in the region—exist for as long as the parent view is shown. Because both beans live at the same time, it is safe to pass a bean reference from the parent task flow to the bounded task flow in the region without risking a null pointer exception or losing state.
Sample Application Overview
Figure 2 shows the runtime view of the application you will build by following the tutorial. The browser page contains two tables: one with department data and one with employee data. It also contains a read-only form showing data in the most recently selected table row.
Figure 2: Updating the parent page form by selecting a row in a region
The page fragments that contain the departments table and the employees table are exposed by two separate regions. Whenever a user selects a new row in either the departments table or the employees table, the selected row data is sent from the bounded task flow in the region to the parent page for display.
Configuring the Sample Application
To follow the steps in this article, you need the studio edition of Oracle JDeveloper 11g Release 2 (188.8.131.52), available as a free download on Oracle Technology Network. You also need access to an Oracle Database instance with an unlocked HR schema. Get started by downloading the o33adf-1916752.zip sample application file and unzipping the file.
The first task is to change the database connection to point to your HR database schema:
1. Launch Oracle JDeveloper 11g Release 2. From the Oracle JDeveloper menu bar, select File -> Open, and navigate to the directory containing the unpacked sample application.
2. Open the OramagSample050613/Starter/RegionParentCommunication folder, and select the RegionParentCommunication.jws file. Click Open to load the workspace.
3. From the View menu, select Database -> Database Navigator, and expand the RegionParentCommunication node to display the hrconn node.
4. Right-click hrconn, and select Properties from the context menu. Edit the database connection information to work with your setup. Test the changes, and click OK.
Next, start the Oracle WebLogic Server instance integrated with Oracle JDeveloper. To do so, select Start Server Instance from the Run menu.
If this is the first time you’ve run the integrated Oracle WebLogic Server, a Create Default Domain dialog box will open. Create a password for the default Oracle WebLogic Server domain, and select an address from those listed for Listen Address. For example, choose localhost rather than leaving the address empty.
Click OK to save the changes and to create and configure the Oracle ADF default domain.
The RegionParentCommunication.jws workspace you opened in Oracle JDeveloper 11g Release 2 is the starting point for the following hands-on instructions. All the task flows, page fragments, and implementation code have already been prepared, so you can focus on configuration of the region-to-parent-page communication.
You will perform the following tasks in this tutorial:
• Set up the departments task flow to accept a managed bean reference as an input parameter, and store the bean reference in a managed bean you create in the departments task flow pageFlow scope. Note that this step has already been done for the employees task flow to save you from unnecessary repetition.
• Override the SelectionListener property of the Oracle ADF Faces table within the DepartmentsView.jsff fragment to post selection change notification to the task flow of the parent page.
• Create a managed bean in view scope of the parent task flow to be passed as an argument to both the employees task flow and the departments task flow.
• Add the two regions to the parent page, and reference the viewScope managed bean as an input parameter.
Because parts of the sample application have already been created, it is important that you follow the hands-on instructions closely. A completed sample, for which you need only to configure database access, is provided in the download.
Setting Up the Department Task Flow
For the departments task flow to hold a reference to a managed bean defined in the parent task flow, you need to create a managed bean in the bounded task flow to store the bean reference. You also need an input parameter that receives the reference at runtime. Follow the steps below to complete those tasks:
1. In the Oracle JDeveloper Application Navigator, expand the ViewController project in the RegionParentCommunication workspace.
2. Expand the Application Sources folder, and navigate to the btf package node within the oramag.mayjun.thirteen.view.beans package.
3. Right-click the btf node, and choose New from the context menu.
4. In the New Gallery dialog box, select General -> Java and then Class.
5. Click OK.
6. In the Create Java Class dialog box, set the value of Name to DepartmentsPageFlowBean.
7. Click the magnifier icon next to the Extends field to open the class browser.
8. In the class browser, select the Hierarchy tab and scroll to the oramag package node.
9. Expand the oramag -> mayjun -> thirteen -> view -> beans -> shared package nodes.
10. Select the TaskFlowPageFlowBean class, and click OK twice.
11. In the Java editor that appears, add the following line above the class constructor:
private ParentHandle parentHandle = null;
When you type the line above, the Importing pop-up dialog box will appear to import the class. Type Alt + Enter to confirm the import.
12. Select the parentHandle variable with the right mouse button, and choose Generate Accessors from the context menu to create a pair of setter and getter methods.
13. Select OK in the Generate Accessors dialog box, after ensuring that the setParentHandle and getParentHandle methods are selected.
14. Save your work.
At this point, you have successfully created the Java class you will configure in the next step as a managed bean in the departments task flow. The ParentHandle class variable will later store the reference to the parent task flow managed bean.
Note that ParentHandle is a Java interface class that defines the contract between the parent flow bean and the managed bean in the bounded task flow that stores the reference. The TaskFlowPageFlowBean class, one of the precreated helper classes in this sample, contains the implementation details for the bounded task flow for passing row data to the parent page. By extending this class, you have fully implemented the functionality required by the sample.
The next step is to configure the DepartmentsPageFlowBean class as a managed bean in pageFlow scope in the departments task flow.
15. In the ViewController project, expand the Web Content -> WEB-INF and btf folders.
16. Double-click the departments-task-flow.xml file to open the task flow in the diagram editor.
17. In the departments-task-flow.xml diagram, click the Overview tab at the bottom.
18. Select the Managed Beans menu entry, and click the green plus (+) icon to the right of the Managed Beans label.
19. Set the Name field value to departmentsFlowBean, and click in the Class field.
20. Click the down-arrow icon on the right and then the Edit menu entry to open the class browser.
21. Select the Hierarchy tab (if it’s not already selected), and scroll to the oramag package node. Expand the oramag -> mayjun -> thirteen -> view -> beans -> btf node, and select DepartmentsPageFlowBean. Click OK.
22. Set the Scope field to pageFlow so the managed bean is accessible as long as the departments task flow instance is active.
23. Save your work.
Next create a new input parameter for the departments task flow that expects an input value of type ParentHandle to save in the departmentsFlowBean you just configured.
24. Go back to the opened departments-task-flow.xml window, and make sure the Overview tab is selected at the bottom.
25. Select the Parameters menu entry, and click the green plus (+) icon to the right of Input Parameter Definitions to create a new input parameter.
26. Set the Name field value to parentHandle, and click in the Class field.
27. Click the down-arrow icon on the right and then the Edit menu entry to open the class browser.
28. Select the Hierarchy tab (if it’s not already selected), and scroll to the oramag package node. Expand the oramag -> mayjun -> thirteen -> view -> beans -> interfaces package nodes, and select the ParentHandle interface class.
29. Click OK.
30. Click in the Value field. Click the down-arrow icon on the right, and choose Expression Builder from the context menu.
31. In the Expression Builder dialog box, expand the ADF Managed Beans and pageFlowScope folders.
32. Expand the departmentsFlowBean node, select parentHandle, and click OK.
33. Check the Required checkbox, and save your work.
In this section, you created a managed bean you will reference as the value target of a new bounded task flow input parameter.