TECHNOLOGY: Oracle ADF

As Published In
Oracle Magazine
September/October 2011

  

All Aboard

By Frank Nimphius

 

Build train models for navigation in bounded task flows.

Developers of Oracle Application Development Framework (Oracle ADF) applications usually implement page navigation by defining control flow cases between activities in unbounded and bounded task flows. An additional navigation configuration option is available for bounded task flows: defining a train. At runtime, a train guides users through a predetermined sequence of views required for completing a multistep task—for example, a series of wizard pages for making multiple form-field edits. In Oracle ADF, you define a train through a train model object, which can be a bounded task flow. In walking through this column, you will explore a completed sample application to learn how to build and use train models in your own Oracle ADF applications.

To begin, download the sample application and unzip the o51adf-409578.zip file. Ensure that you’re using the studio edition of the Oracle JDeveloper 11g 11.1.1.5 (or later) release, available as a free download on Oracle Technology Network. The application uses the HR schema available by default in Oracle Database.

Sample Application Overview

Launch Oracle JDeveloper and browse to the directory where you unzipped the sample application. Open the AdfTrainSample.jws workspace from inside the AdfTrainSample folder. Before proceeding, adjust the properties of the hrconn connection in the Application Resources panel of the Application Navigator and confirm that you can successfully connect to the HR schema.

The sample application consists of two bounded task flows:

  1. adf-region-btf.xml, shown in Figure 1, is the parent bounded task flow, which is exposed as a region in Main.jspx. This task flow contains two view activities and one task flow call activity. The dashed arrows between the activities indicate that this bounded task flow is configured as a train model and the activities therein as train stops that users navigate at runtime.

    o51adf figure 1

    Figure 1: Parent task flow exposed as an Oracle ADF region

  2. employees-btf.xml, shown in Figure 2, is a subprocess called from the task flow call activity in the adf-region-btf.xml task flow. It represents a three-step form-entry wizard for editing employee records, also configured for train navigation. o51adf figure 2

    Figure 2: Subtask flow for editing employee records

 

To run the sample application, expand the ViewController project in the Application Navigator, right-click the Main.jspx page in the Web Content folder, and choose Run. On the browser page that opens, select an employee record and click either the Employee Edit train stop or the Create New Employee button. Both actions enter the employees-btf subtask flow, enabling you to edit the selected (or newly created) employee’s data. Use the train UI component or the Next and Previous buttons to continue navigation and complete the task. On the last wizard page, click either Cancel to start over again or Submit to see a summary page with the changes applied. (To preserve the state of your HR schema, the sample application does not commit changes to the database.)

Enabling Train Models

You can declaratively configure a bounded task flow to expose a train model for use on the pages and page fragments it contains by setting the task flow’s Train property. On the pages and page fragments, you use the Oracle ADF Faces af:train and af:trainButtonBar components to render the train model in the UI.

Expand the sample application’s View Controller project in the Application Navigator. Open the Web Content folder and its WEB-INF folder, and then double-click employees-btf.xml to open it in the task flow visual editor.

Next, open the Oracle JDeveloper Structure window (Ctrl-Shift-S). Under ADF Task Flow, select task-flow-definition - employees-btf. Open Oracle JDeveloper’s Property Inspector feature (Ctrl-Shift-I), and scroll to the Behavior section. You can see that the Train property is set to true to expose the task flow train model at runtime. (The default value is false.)

Defining Train Stops and the Navigation Sequence

After enabling a bounded task flow to expose a train model, you need to define view activities and task flow call activities as train stops. To add an existing view or task flow call activity to the train model, select the activity in the visual editor, right-click, and then select the Train option to create (or, later, to change) the train stop setting. Any view and task flow call activities you add to the task flow diagram are automatically added to the sequence of train stops.

The navigation sequence is defined initially by the order in which view activities and task flow call activities are added as train stops. You can easily change this order via the Train option in the context menu associated with each activity.

Train stops are further configured with the Property Inspector. To see how, select the EmployeeDetails view activity in the sample application’s employees-btf.xml task flow and open the Property Inspector. Scroll to the Train Stop section to see the train stop properties, as shown in Figure 3.

o51adf figure 3

Figure 3: Train stop configuration properties for the EmployeeDetails view activity

The Train Stop section appears in the Property Inspector only if the bounded task flow’s Train property is set to true and the selected activity is either a view activity or a task flow activity.

Train Stop Properties

As you can see in Figure 3, train stops are configured with five properties:

  1. The Train Stop property is set to false by default. When set to true, it indicates that the view or task flow call activity is a train stop. You set this property at design time and cannot change it at runtime.

  2. The Outcome property enables you to associate a control flow name with a train stop to define an alternative navigation case. The Outcome property can be read from Java code at runtime but not changed then.

  3. The Sequential property defines the order in which users navigate the train stops. If a train stop’s Sequential property is set to true, users can access that stop only if they have already visited the preceding stop. A value of false defines nonsequential navigation, enabling the user to select any train stop whose Skip property is not set to true. You can use Expression Language (EL) to define the Sequential property value for a train stop dynamically. The sample application for this column demonstrates this usage.

  4. The Skip property disables a train stop so that users cannot navigate to it. Like the Sequential property, the Skip property can be dynamically changed at runtime.

  5. The Ignore property prevents a train stop from rendering in the UI. Although you can use EL to set the Ignore property value dynamically at runtime, it can be changed only upon task flow initialization. Once a task flow is rendered, the Ignore property is immutable.

Building the Train User Interface

Oracle ADF Faces provides two UI components for displaying train models in your JavaServer Faces pages and page fragments:

  1. The train component, af:train, displays the train model as a horizontal or vertical line with icons indicating the stops. The train component is used for both sequential and nonsequential navigation.

    To define display names for each stop, you edit the task flow. If it’s not open already, double-click the employees-btf.xml file in the Application Navigator and expand the EmployeeDetails view activity node in the Structure window. Expand the train-stop node, as shown in Figure 4, to see the Display Name configuration. You add the display name element by using the right-click context menu on the train-stop node and selecting Insert inside train-stop -> Display Name. You then edit the Display Name value with the Property Inspector.

    o51adf figure 4

    Figure 4: Display name configuration for a train stop in the Structure window

    You can also use EL to read the display-name value from a message bundle to support translated labels for internationalized applications.

  2. The trainButtonBar component renders the train model with buttons for forward and backward navigation. Navigation with trainButtonBar is strictly sequential and does not skip over disabled train stops. If a train stop is configured with the Skip property set to true, the trainButtonBar will stop there.

The Oracle ADF Faces train and trainButtonBar components are located in the Oracle JDeveloper Component Palette window under ADF Faces -> Common Components. When you drag either component to a page or a page fragment in a bounded task flow whose Train property is set to true, Oracle JDeveloper automatically sets the component’s value property, as shown in Listing 1, for each component.

Code Listing 1: Automatic default settings for train components

<af:train id="t2"
   value="#{controllerContext.currentViewPort.taskFlowContext.trainModel}"/>

<af:trainButtonBar id="tbb1" 
value="#{controllerContext.currentViewPort.taskFlowContext.trainModel}"/>

The EL string within each of these component tags references the train model of the active bounded task flow to determine the current stop in the navigation sequence. By doing so, it also determines the preceding and next stops in a sequential train.

Customizing the Train User Interface

To customize the train stop behavior—for example, to add an action listener to a train stop, to mark a train stop as required, or to use your own custom icons for train stops—you must change the train component tag, as shown in Listing 2.

Code Listing 2: Changing the settings of a train component

<af:train id="t1" var="trainNode"  
   value="#{controllerContext.currentViewPort.taskFlowContext.trainModel}">
   <f:facet name="nodeStamp">
    <af:commandNavigationItem text="#{trainNode.textAndAccessKey}"
        id="cni1" visited="#{trainNode.visited}"  
        disabled="#{trainNode.disabled}"
        action="#{trainNode.action}"
        immediate="false"
        actionListener="..."/>
    </f:facet>
</af:train>
 

In this changed tag configuration, af:commandNavigationItem is added to the nodeStamp facet to replace the default train stop renderer. The EL trainNode variable is defined on the var attribute of af:train to access the train stop properties defined in the train model. 

Note that the trainNode variable is also accessible from a managed bean (MBean) during train rendering. An example that uses this option to set the af:commandNavigationItem component’s immediate property is explained in the “Enabling Backward Navigation” section later in this column.

Enabling Reuse via a Page Template

As you know from the preceding section, the af:train and af:trainButtonBar components reference the bounded task flow train model by using the generic expression

#{controllerContext.currentViewPort
.taskFlowContext.trainModel} 

Because this string does not include the task flow name, train configuration is a good candidate for use in page templates.

However, when you add a train component to a template, the value property is not automatically set, as it is when you add it directly to a page. To set it for a template, open the Property Inspector for the selected train component and click the arrow icon next to the value property. Then choose the Expression Builder menu option to declaratively compose the expression

#{controllerContext.currentViewPort
.taskFlowContext.trainModel}

The sample application uses a page template, PageFragmentTemplate.jspx, to add the train definition to all views in the bounded task flows. In the Application Navigator, the template is under the ViewController project, in the templates folder inside the Web Content folder. When you reference an MBean from the train component configuration, as the sample application does, make sure the MBean is configured with the same name in all bounded task flows that use the page template.

Including Method Call Activities in Train Navigation

Train navigation occurs among view and task flow call activities, but in some use cases, you might also want to call a method as part of the navigation. To include method call activities in train navigation, you set the train stop’s Outcome property to reference a wildcard control flow case.

As you can see in Figure 2, the HumanResourceDetails task flow activity’s Outcome property is set to humanResourceDetailsStop to invoke an MBean method before the view activity is accessed. By using a router activity instead of a method call activity, you can even divert train navigation based on an EL-accessible condition.

Suppressing Model Validation

If your application includes a train that uses multiple Oracle ADF-bound forms that update the same data control, you might need to disable model validation. Otherwise, errors can occur if required fields are located later in the navigation sequence.

Next Steps


READ more about Oracle ADF
 Oracle ADF
Oracle Fusion Middleware Fusion Developer’s Guide for Oracle Application Development Framework 11g Release 1 (11.1.1.4.0)
Oracle Fusion Developer Guide: Building Rich Internet Applications with Oracle ADF Business Components and Oracle ADF Faces (McGraw-Hill, 2010)
 Oracle ADF Insider
 

READ more Nimphius
 Oracle ADF Code Corner
OTN Harvest blog
 

DISCUSS Oracle JDeveloper and Oracle ADF
 Oracle JDeveloper Oracle Technology Network forum
 

DOWNLOAD
 the sample application for this column
Oracle JDeveloper and Oracle ADF
Oracle JDeveloper 11g Release 2
 

READ more
 about this release

To disable Oracle ADF model validation temporarily, set the SkipValidation property in a view’s page definition file to custom. In the sample application, Oracle ADF model validation is disabled when users create a new employee record. To see the configuration for the EmployeeDetails view activity, select the EmployeeDetailPageDef.xml file in the oramag.adf.sample.view .pageDefs package of the ViewController project’s Application Sources folder. Open the Structure window and select the EmployeeDetailPageDef root node to see the SkipValidation property setting in the Property Inspector.

Enabling Backward Navigation

In a multistep form edit, as shown in Figure 2, users might need to navigate to a previous step without providing all the required information on the current page. To enable backward navigation without validating the current form, you must set the train stop’s immediate property to true, using the following steps:

  1. Customize the train user interface with a commandNavigationItem (as explained under “Customizing the Train User Interface,” above).

  2. Create an MBean method that references #{trainNode} to compare the rendered train stop with the current selected stop.

  3. If the rendered train stop is before the current train stop, the method should return true. Otherwise, the method should return false.

  4. Using EL, reference the MBean from the immediate property of the commandNavigationItem.

The sample application implements the immediate = true behavior in the train component in the PageFragmentTemplate.jspx template. The MBean referenced by commandNavigationItem is configured in both bounded task flows.

Navigating the Train Model from Java Code

You might have a use case that requires programmatic navigation in a train model. For example, you might want to create a “finish” option that skips all remaining steps in a train sequence or build your own trainButtonBar solution that can step over train stops that are marked as skipped.

The JobDetails view activity in the sample application’s employees-btf.xml bounded task flow definition contains two af:commandButton components, for forward and backward navigation. The button action properties reference an MBean method that accesses the train model to determine what the next navigation stop is and whether that stop needs to be skipped. To determine if a train stop needs to be skipped, the MBean method accesses the same HashMap bean that is used to configure the Skip property on the train stops in the bounded task flow.

Conclusion

Train navigation is a valuable addition to control flow cases in Oracle ADF bounded task flows. In this column, you’ve learned how to create train models from bounded task flows, including some advanced techniques you can use in your Oracle ADF application projects. To learn more about creating train models, see Section 18.8, “Creating a Train,” in Oracle Fusion Middleware Fusion Developer’s Guide for Oracle Application Development Framework 11g Release 1 (11.1.1.5.0)


Frank Nimphius is a senior principal product manager for Oracle JDeveloper and Oracle Application Development Framework. He is a coauthor of Oracle Fusion Developer Guide: Building Rich Internet Applications with Oracle ADF Business Components and Oracle ADF Faces (McGraw-Hill, 2010). 

Send us your comments