DEVELOPER: Frameworks

Task and You Shall Receive

By Steve Muench

Visually assemble applications from reusable task flows.

JavaServer Faces (JSF) provides a simple, declarative facility for controlling how an end user navigates from one page to another. Developers quickly realize, however, that they need to augment these basic navigation rules with custom code to implement real-world page flows requiring conditional page routing, page initialization logic, and transaction handling. In the upcoming Oracle JDeveloper 11g release, Oracle Application Development Framework (Oracle ADF) extends the core JSF page flow facility with powerful task-oriented features that eliminate the need for most of this custom coding. This column examines the basics of this new task flow feature to show how it simplifies the building of applications.

To begin, download the starter workspace and ensure that you’re using the Oracle JDeveloper 11.1.1.0 Technology Preview 4 release, available as a free download on the Oracle Technology Network at oracle.com/technetwork/products/jdev/11. Start by extracting the contents of the o58frame.zip file and opening the FrameworksSepOct2008.jws workspace in Oracle JDeveloper. Note that the Model project in the workspace defines a Dept entity object, a DeptView view object, and an HRModule application module. Before proceeding, adjust the properties of the scott connection in the Application Resources zone of the Application Navigator until you can successfully test a connection to a SCOTT schema. If you need to create the tables, use the provided CreateDeptEmpTables.sql.

Understanding Task Flows

An Oracle ADF task flow encapsulates a set of activities into a logical group. A view activity displays pages to the end user, whereas other kinds of activities perform actions. When you create a task flow, you decide if it will be bounded or unbounded . An unbounded task flow is free-form and allows the user to start at any page. In contrast, a bounded task flow is a self-contained unit of work that behaves like a visual function. It has a single entry point, a set of input parameters, and one or more ways to return control (and optionally values) to the calling flow. When you create a bounded task flow, you also decide whether its view activities represent entire pages or only page fragments. If you use full pages, your bounded task flow can be incorporated easily into other task flows wherever necessary. If you use page fragments instead, your task flow is a reusable region you can drop into other pages. The task flows in this column use full pages; you’ll learn about building reusable regions of page fragments in the next column.

Because a task flow has a nice visual representation, the easiest way to understand what it does is to look at an example. In the Application Navigator, expand the Web Content folder of the ViewController project as well as the Page Flows folder it contains and double-click the modify-department task flow to open it in the editor. You’ll see the diagram shown in Figure 1: a set of activity icons of different types, connected by control flow lines.

In Figure 1, the colored circle highlight identifies RouteByMode as the default (initial) activity and SaveChanges and CancelChanges as task flow return activities, and these activities identify modify-department as a bounded task flow. Discover the different kinds of activities the diagram employs by hovering your cursor over the different icons in the editor. RouteByMode is a router activity that performs conditional navigation. FindDepartment and CreateDepartment are method call activities that invoke application logic or built-in operations. EditDepartment is a view activity that displays a page to the end user, and SaveChanges and CancelChanges are task flow return activities that pass control back to the calling task flow.

The modify-department task flow starts by conditionally invoking application logic to either find an existing department or create a new department and then shows a page for the data entry. From there, the user can complete the task by either saving the changes or canceling them. The diagram in the editor (and Figure 1) communicates effectively what the modify-department task flow does.

Figure 1: The modify-department task flow in the editor

Exploring a Bounded Task Flow

Let’s observe the task flow’s input parameters. In the Structure window, expand the ADF Task Flow node, right-click the task-flow-definition node beneath it, and select Go to Properties . In the Property Inspector, select the Parameters section to see that two input parameters named mode and rowKeyStrToEdit are defined. When this modify-department task flow is invoked, the caller passes values for these parameters. You can see that the mode parameter is required, whereas the rowKeyStrToEdit parameter is optional. The expression language (EL) expression #{pageFlowScope.mode} in the Value column of the Input Parameter Definitions table indicates where the Oracle ADF runtime will save the mode input parameter value for reference by the activities and pages in the task flow. The convenient pageFlowScope is a map of name/value pairs where task flow input parameter values can be saved for the duration of the task flow.

Select the RouteByMode activity in the modify-department task flow diagram, and in the Common section of the Property Inspector, note how EL expressions are configured to conditionally choose the navigation outcome. If the pageFlowScope.mode attribute equals Add , then the RouteByMode activity uses the Create control flow to route control to the CreateDepartment method call activity to create a new department. If this pageFlowScope.mode attribute equals Edit , the RouteByMode activity uses the Find control flow and invokes the FindDepartment activity instead. Both of these method call activities forward control to the EditDepartment view activity.

Double-click the EditDepartment view activity in the modify-department task flow to open the corresponding EditDepartment.jspx page in the visual editor. Select the Output Text component in the panel box at the top of the page; in the Property Inspector, the EL expression, in its Value property, uses conditional expressions involving the mode attribute to output an appropriate message. Click Save in the visual editor to observe that its Action property is set to the Save outcome, which will forward control to the SaveChanges task flow return activity when that button is clicked. Similarly, the Cancel button’s Action property is set to the Cancel outcome, which will navigate to the CancelChanges return activity.

Another key feature of a bounded task flow is its optional declarative transaction handling. Let’s see how the modify-department task flow leverages this capability. Click the modify-department task flow editor’s tab to bring it to the front. Select the task-flow-definition node in the Structure window, and select the Behavior section in the Property Inspector. Note that under the Transaction heading, the transaction property is set to requires-transaction , which tells the Oracle ADF runtime that the task flow is transaction-aware. The data-control-scope setting shared indicates that when this task flow is called, any data controls it uses will be included in the same transaction as the calling page flow. Select the SaveChanges task flow return activity in the diagram, and note in the Behavior section of the Property Inspector that its End Transaction property is set to commit . This indicates that when this return activity is executed, Oracle ADF should automatically commit the transaction. In contrast, for the CancelChanges return activity, the End Transaction property is configured to perform a rollback.

Configuring the Method Activities

In the modify-department task flow, make note of the warning symbols on the FindDepartment and CreateDepartment method call activities. This indicates that these activities are not fully configured yet. To remedy the situation, expand the Data Controls section of the Application Navigator and expand HRModuleDataControl , the Departments data collection, and the Operations folder it contains. Drag the Create operation node that appears there, and drop it onto the CreateDepartment method call activity. Select the CreateDepartment activity in the diagram, and in the Common section of the Property Inspector, select Edit from the fixed-outcome property list. Repeat these steps to drag the setCurrentRowWithKey operation for the Departments data collection from the Data Controls palette and drop it onto the FindDepartment method call activity. As before, set the fixed-outcome property to Edit .

Next, configure the parameter for the setCurrentRowWithKey action binding related to this method call. Right-click the FindDepartment activity and choose Edit Binding . In the Parameters section, enter the EL expression #{pageFlowScope.rowKeyStrToEdit} in the Value column for the rowKey parameter of the action binding and then click OK . Finally, ensure that validation is disabled on the page definitions related to the two action bindings. To do this, right-click the FindDepartment activity and choose Go to Page Definition . In the Structure window, select the top-level node and ensure that the SkipValidation property is set to true. Repeat the same steps for the CreateDepartment activity.

Calling a Task Flow

As a last step before running the application, we’ll finish configuring an unbounded task flow that invokes the bounded modify-department task flow above. Double-click the adfc-config XML file under the Page Flows folder in the Application Navigator to open it in the editor. This task flow contains the BrowseDepartments view activity that forwards to a modify-department task flow call activity that I created by simply dropping the modify-department task flow from the Application Navigator onto the diagram. The modify-department task flow call activity appears with a red X icon, because the required mode parameter that the modify-department bounded task flow expects has not yet been configured.

Open the BrowseDepartments.jspx page in the visual editor, and select the Add button. In the Property Inspector, you can see that its Action property triggers the AddOrEdit control flow rule. Selecting the af:setActionListener component (nested inside this af:commandButton component in the Structure window), you can see that it sets the constant value Add into an attribute named mode in requestScope. Similarly, note that the Edit button’s Action property triggers the same AddOrEdit control flow rule and has nested setActionListener components that set the constant value Edit into requestScope.mode as well as setting the row key of the current row—by using the expression #{bindings.Departments.rowKeyStr} —into the rowKeyStr attribute in requestScope. So these buttons are already configured to set appropriate values into requestScope attributes that we can use as inputs to the task flow call.

Click the adfc-config.xml editor’s tab to bring it to the front, and select the modify-department task flow call activity. In the Property Inspector, select the Parameters section and in the Input Parameters table, enter the EL expression #{requestScope.mode} as the value of the mode parameter, and enter the EL expression #{requestScope.rowKeyStr} as the value of the rowKeyStrToEdit parameter. This configures the task flow call to “pull” its input parameters from the request scope locations where the buttons have temporarily stored these values during the current request.

Because the default run configuration of the ViewController project is already configured to have the BrowseDepartments activity of the adfc-config task flow as its default run target, you can test the application by right-clicking the ViewController project in the Application Navigator and choosing Run . When the browse page appears, you’ll see that you can browse, add, and edit departments like a champion, with the unbounded and bounded task flows working together to handle all of the common application logic and transaction handling without a line of code!

As usual, we’ve been able to get only a glimpse of this powerful new task flow feature in the space available here. For more-detailed information on this feature, I encourage you to read the chapters in Part III of the Fusion Developer’s Guide for Oracle ADF 11g, available on OTN at oracle.com/technetwork/products/jdev/11.

Steve Muench is a consulting product manager for Oracle JDeveloper and an Oracle ACE. Since 1990 he has developed and supported Oracle tools and XML technologies and continues to evangelize them. Muench coauthored the Oracle ADF Developer’s Guide for Forms/4GL Developers (Oracle, 2006) and shares tips and tricks on OTN and in his Dive into ADF blog.