Skip Headers
Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1)

Part Number B31974-02
Go to Documentation Home
Home
Go to Book List
Book List
Go to Table of Contents
Contents
Go to Feedback page
Contact Us

Go to previous page
Previous
Go to next page
Next
View PDF

17 Creating Complex Task Flows

This chapter describes using advanced features of ADF task flows and includes the following sections:

17.1 Using Initializers and Finalizers

An initializer is custom code that is invoked when an ADF bounded task flow is entered. You specify both the initializer and finalizer as an EL expression for a method on a managed bean, for example, #{pageFlowScope.modelBean.releaseResources}.

There are two techniques for running initializer code at the beginning of the ADF bounded task flow, depending on whether the task flow may be reentered via a browser Back button:

A finalizer is custom code that is invoked when an ADF bounded task flow is exited via a task flow return activity or because an exception occurred. The finalizer is a method on a managed bean. Common finalizer tasks include releasing all resources acquired by the ADF bounded task flow and perform cleanup before exiting the task flow.

17.2 Managing Transactions

A transaction is a persisted collection of work that can be committed or rolled back together as a group. You can use an ADF bounded task flow to represent a transactional unit of work and to declaratively manage transaction boundaries. In the Fusion Order Demonstration application, the customer registration and employee registration task flows were both implemented with the use of task flow return activities. The Cancel button implements rollback in the task flows. The OK button on the review.jsff page fragment implements Commit functionality.

An end user can navigate from the Shopping Cart to initiate a backorder request for an out-of-stock item. The back order request application is implemented as an ADF bounded task flow that initiates a new transaction upon entry.

Transaction options on the called task flow definition specify whether a called ADF bounded task flow should join an existing transaction, create a new one, or create a new one only if there is no existing transaction.

If the called ADF bounded task flow is able to start a new transaction (based on the transaction option that you selected), you can specify whether the transaction will be committed or rolled back when the task flow returns to its caller. The commit and rollback options are set on the task flow return activity that returns control back to the calling task flow. The same task flow that starts a transaction must also resolve the transaction.

In a called task flow definition, you can specify two different return task flow activities that result in either committing or rolling back a transaction in the called ADF bounded task flow. Each of the task flow return activities passes control back to the same calling task flow. The difference is that one task flow return activity specifies the commit option, while the other specifies the rollback option. As shown in Figure 17-1, if transaction processing successfully completes, control flow passes to the success task flow return activity, which specifies options to commit the transaction. If the transaction is cancelled before completion, the cancel task flow activity specifies options to roll back the transaction.

Figure 17-1 Task Flow Return Activities in Called ADF Bounded Task Flow

Multiple task flow return activities.

If no transaction option is specified, a transaction is not started on entry of the called ADF bounded task flow. A runtime exception is thrown if the ADF bounded task flow attempts to access transactional services.

If you want changes the user made within the called ADF bounded task flow to be discarded when it is exited, you can specify the restore-save-point option on the task flow return activity. The ADF Controller will roll back to the previous ADF Model save point that was created when the ADF bounded task flow was entered. The restore-save-point option applies only to cases when an ADF bounded task flow is entered by joining an existing transaction (either the requires-existing-transaction or requires-transaction option is also specified) and a Save Point is created upon entry.

Best Practice:

You can use a return activity to call the commit action or use a button bound to the commit action. If possible, use a task flow return activity. Using a task flow return activity will commit all data controls used by the ADF task flow. It also makes it easier to see where your application is doing commits and rollbacks, and is therefore easier to maintain.

You must use invokeAction if:

  • You want to commit before the end of an ADF task flow.

  • You are not using the ADF controller.

  • The task flow uses multiple data controls and you do not want to commit all of them.

17.2.1 How to Enable Transactions in an ADF Bounded Task Flow

Before you begin, you should have two task flows. One calls the second ADF bounded task flow using a task flow call activity. The called ADF bounded task flow will specify a transaction option that defines whether or not a new transaction will be created when it is called. It will also contain a task flow return activity that specifies an outcome upon return to the caller.

To enable an ADF bounded task flow to run as a transaction:

  1. In the editor, open the called ADF task flow.

  2. In the Overview tab for the called ADF bounded task flow, click Behavior and expand the Transaction section.

  3. Choose one of the following from the transaction drop-down list:

    • requires-existing-transaction: When called, the ADF bounded task flow participates in an existing transaction already in progress.

    • requires-transaction: When called, the ADF bounded task flow either participates in an existing transaction if one exists, or starts a new transaction upon entry of the ADF bounded task flow if one doesn't exist.

    • new-transaction: A new transaction is always started when the ADF bounded task flow is entered, regardless of whether or not a transaction is in progress. The new transaction is completed when the ADF bounded task flow exits.

    If you do not choose any item, the called ADF bounded task flow does not participate an any transaction management.

    Note:

    After choosing a transaction option, you may also need to check the data-control-scope option for the bounded task flow to determine if there are any interactions between the options. See Section 15.3.1, "What You May Need to Know About Managing Transactions" for more information.
  4. If you choose requires-existing-transaction or requires-transaction, you can optionally select true in the no-save-point drop-down list.

    If you select true, an ADF Model save point will not be created on task flow entry. An ADF Model save point is a saved snapshot of the ADF Model state. Selecting true means that overhead associated with a save point is not created for the transaction.

  5. In the editor, select the task flow return activity in the called ADF bounded task flow.

  6. In the Property Inspector, click Behavior.

  7. If the called task flow definition supports creation of a new transaction (task flow definition specifies requires-transaction or new-transaction options), select one of the following in the End Transaction dropdown list:

    • commit: commits the existing transaction to the database.

    • rollback: rolls back a new transaction to its initial state on task flow entry. This has the same effect as cancelling the transaction.

  8. In the restore-save-point drop down list, select true if you want changes the user made within the called ADF bounded task flow to be discarded when it is exited. The savepoint that was created upon task flow entry will be restored.

17.2.2 What Happens When You Specify Transaction Options

Example 17-1 shows the metadata for transaction options on a called task flow definition. The <new-transaction> element indicates that a new transaction is always started when the ADF bounded task flow is entered.

Example 17-1 Called Task Flow Definition Metadata

<task-flow-definition id="trans-taskflow-definition">     
    <default-activity>taskFlowReturn1</default-activity>
    <transaction>
      <new-transaction/>
    </transaction>
    <task-flow-return id="taskFlowReturn1">
      <outcome>
        <name>success</name>
        <commit/>
      </outcome>
    </task-flow-return>
  </task-flow-definition>

Example 17-1 also shows the metadata for transaction options on the task flow return activity on the called task flow. The <commit/> element commits the existing transaction to the database. The <outcome> element specifies a literal outcome, for example, success, that is returned to the caller when the ADF bounded task flow exits. The calling ADF task flow can define control flow rules based on this outcome to handle control flow upon return (see Section 14.7, "Using Task Flow Return Activities" for more information).

17.3 Reentering an ADF Bounded Task Flow

To deal with cases in which the end user clicks the back button to navigate back into an ADF bounded task flow that was already exited, you can specify task-flow-reentry options for the task flow definition. These options specify whether a page in the ADF bounded task flow can be reentered.

Upon reentry, ADF bounded task flow input parameters are evaluated using the current state of the application, not the application state existing at the time of the original ADF bounded task flow entry.

Note:

Different browsers handle the back button differently. In order to ensure that back button navigation is properly detected across all browsers, the view activities within the task flow need to be properly configured. When a task flows uses the reentry-not-allowed or reentry-outcome-dependent option, the redirect attribute on each view activity within the task flow should be set to true. See Section 14.3, "Using URL View Activities" for more information on how to configure view activities.

17.3.1 How to Set Reentry Behavior

To set reentry behavior:

  1. Open the ADF bounded task flow diagram in the editor.

  2. Click the Overview tab.

  3. Click Behavior.

  4. In the Task Flow Reentry list, choose one of the following:

    • reentry-allowed

    • reentry-not-allowed

    • reentry-outcome-dependent

17.3.2 How to Set Outcome-Dependent Options

The following steps apply only to ADF bounded task flows that have specified the reentry-outcome-dependent option.

  1. In the ADF bounded task flow, add a task flow return activity. (See Section 14.7, "Using Task Flow Return Activities" for more information).

  2. In the task flow diagram, select the task flow return activity.

  3. In the Common page of the Property Inspector, expand the Outcome section.

  4. In the name field, enter the name of literal outcome, for example, success or failure.

  5. In the Property Inspector, click Behavior.

  6. In the Reentry drop-down list, select either:

    • reentry-allowed

    • reentry-not-allowed

17.3.3 What You Should Know About Managed Bean Values Upon Task Flow Reentry

When an end user reenters an ADF bounded task flow using the browser Back button and reentry is allowed (either by setting reentry-allowed on the bounded task flow or a combination of reentry-outcome-dependent on the bounded task flow and reentry-allowed on the task flow return activity as described in Section 17.3.1 and Section 17.3.2), the value of a managed bean on the reentered task flow is set back to its the original value, the same value that it was before the end user left the parent task flow.

This results in the managed bean value resetting back to its original value before a view activity in the reentered task flow renders. Any changes that occurred before reentry are lost. To change this behavior, specify the <redirect> element on the view activity in the reentered bounded task flow. When the end user reenters the bounded task flow using the Back button, the managed bean has the new value from the parent task flow, not the original value from the child task flow that is reentered.

17.4 Handling Exceptions

During execution of an ADF task flow, exceptions can occur that may require some kind of exception handling, for example:

To handle exceptions thrown from an activity or caused by some other type of ADF Controller error, you can create an exception handler for an ADF bounded or unbounded task flow.

When an exception is raised within the task flow, control flow passes to the designated exception handling activity. For example, the exception handling activity might be a view that displays an error message. Or the activity might be a router that passes control flow to a method based on an EL expression that evaluates the type of exception, for example, #{someException="oracle.adf.Controller.ControllerException"}.

After control flow passes to the error handling activity, flow from the activity uses standard control flow rules (see Section 13.1.3, "Control Flows" for more information).

You can optionally specify an exception handler for both ADF bounded and unbounded task flows. If specified, the task flow can have only a single exception handler. However, a task flow called from inside another task flow can have a different exception handler than the one for the caller. In addition, a region on a page can have a different exception handler than the task flow containing the page. The exception handler activity can be any supported activity type, for example, a view or router activity.

If an ADF bounded task flow does not have a designated exception handler activity, control passes to an exception handler activity in a calling ADF bounded task flow, if there is a calling task flow and it contains an exception handler activity. The exception is propagated up the task flow stack until either an exception handler activity or the top-level ADF unbounded task flow is reached. If no exception handler is found, the exception is propagated to the web container.

You can designate a exception handler activity for an ADF bounded task flow running as an ADF region. If an exception occurs in the bounded task flow and it is not handled by the task flow's exception handler, the exception is not propagated up the task flow stack of the parent page. Instead, it becomes an unhandled exception.

To designate an activity as an exception handler for a task flow:

  1. Right-click the activity in the task flow diagram, then choose Mark Activity > Exception Handler.

    A red exclamation point is superimposed on the activity in the task flow to indicate it is an exception handler.

    An activity designated as an exception handler.
  2. To unmark the activity, right-click the activity in the task flow diagram, then choose Unmark Activity > Exception Handler.

    If you mark an activity as an exception handler in a task flow that already has a designated exception handler, the old handler is unmarked.

17.4.1 Handling Exceptions During Transactions

As a best practice, any ADF bounded task flow representing a managed transaction should designate an exception handling activity. When running an ADF bounded task flow managed transaction, the ADF Controller attempts to commit the transaction when it reaches a task flow return activity identified in metadata for a commit (see Section 17.2, "Managing Transactions" for more information). If the commit throws an exception, control is passed to the ADF bounded task flow's exception handling activity.

This provides the end user with a chance to correct any data she may have added on a page and then reattempt to commit it, for example, by clicking a Save button. You can use the exception handling activity (for example, a view activity) to display a warning message on a page that tells the user to correct the data and attempt to commit it again.

17.4.2 What Happens When You Designate an Exception Handler

After you designate that an activity is the exception handling activity for a task flow, the task flow metadata updates with an <exception-handler> element that specifies the id of the activity, as shown in Example 17-2.

Example 17-2 <exception-handler> element

<exception-handler>MyView</exception-handler>

17.4.3 What You May Need to Know About Handling Validation Errors

For validation errors on a JSF page, you can rely on standard JSF to attach validator error messages to either specific components on a page or the whole page. A component-level validator typically attaches an error message inline with the specific UI component. There is no need to pass control to an exception handler activity.

In addition, Oracle recommends that your application define validation logic on data controls that are executed during the Validate Model Updates phase of the JSF lifecycle. By doing so, data errors are found as they are submitted to the server without waiting until attempting the final commit.

Validations done during the Validate Model Updates typically do not have direct access to the UI components because the intention is to validate the model after the model has been updated. These validations are often things like checking if dependent fields are in sync. In these cases, the error message is usually attached to the whole page, which this logic can access.

Errors detected during the Validate Model Updates phase should be attached to the JSF page, and FacesContext.renderResponse()should be called. This signals that following this phase, the current (submitting) page should be rendered showing the attached error messages. There is no need to pass control to an exception handler activity.

For more information, see Chapter 8, "Implementing Validation and Business Rules Programmatically".

17.5 Saving for Later

Saving for later captures a snapshot of a Fusion web application at a specific instance called a save point. This allows you to retain the current state of the task if a user leaves a page without finalizing it. For example, an end user may need to stop in the middle of completing a page containing an employee profile form because it is the end of the business day or because additional information is required to answer questions.

You can use the save point restore activity to restore whatever was captured at the original save point. This enables the end user to complete the rest of the task at a future date, with former unsaved values restored to the page. For example, you could create a page containing a drop-down list of save point ids and a button. When an end user selects a save-point-id and clicks the button, the application executes the save point restore activity. See Section 14.8, "Using Save Point Restore Activities" for more information.

There are two categories of saving for later:

Implicit save points are deleted when the task flow at the bottom of the stack completes or a new implicit save point is generated, whichever comes earlier.

You can call the createSavePoint()API to create a save point, identified by its save-point-id. A save point captures a snapshot of an application at a specific instance. For an explicit save, this includes everything from the time the save point is created in the originating task flow down through the call stack. Explicit save points are automatically removed when an ADF bounded task flow at the bottom of the task flow call stack completes. createSavePoint() is located under ADF Controller Objects -> controllerContext -> savePointManager.

For an implicit save, this includes everything from the time the save point is created in the originating task flow, both down and up the call stack.

Implicit save points are created for an application only if you have set the enable-implicit-savepoints property to true in the adf-config.xml configuration file. The save point and application state information are saved in a database.

State information for the application at the save point is also saved, as shown in Table 17-1.

Table 17-1 Saved Application State Information

Saved Sate Information Description

User Interface State

UI state of the current page, including selected tabs, selected checkboxes, selected table rows, and table column sort order.

This assumes the end user cannot select the browser back button on save point restore.

Managed Beans

State information saved in several possible memory scopes, including session and pageFlow scope. The managed beans must be serializable in order to be saved. If you have pageFlowScope beans that are not serializable and you attempt to create a save point, a runtime exception occurs.

Request scope is not supported since its lifespan is a single HTTP request and can't be used to store cross request application state.

Save for later will not save and restore application scoped managed beans since they're not passivated in failover scenarios. Therefore, the application is always responsible for ensuring that all required application-scoped state is available.

Potential naming conflicts for managed beans already existing within the session scope at restore time will not occur because multiple managed beans using the same name shouldn't be implemented within an application.

Navigation State

Task flow call stack, which ADF Controller maintains as one task flow calls another at runtime.

The task flow call stack tracks where the end user is in the application and the navigational path for getting there. The task flow stack also identifies the starting point of any persisted data transactions originated for the end user.

ADFm Model State

Fusion web applications use ADFm to represent the persisted data model and business logic service providers. The ADFm model holds any data model updates made since beginning the current bounded task flow. The model layer determines any limits on the saved state lifetime. See Chapter 36, "Application State Management" for more information.


The same save-point-id can be used when the same user repeatedly performs a save for later on the same instance of a task flow within the same browser window within the same session. If a user performs a save for later following every page of a task flow, only one save-point-id will be created. It is overlaid each time a save for later is performed.

17.5.1 How to Add Save For Later Capabilities

To enable save for later, you must call the createSavePoint()method to create a save-point-id. Later, you use the save point restore activity to restore application state and data associated with a save-point-id (for more information, see Section 17.5.2, "How to Restore Save Points").

A save point is stored in a database table. The table used to store save points is called ORADFCSAVPT. If this table does not exist within the database, it will automatically be created along with the first save point. When the save point is restored, the save point is deleted from the database.

Figure 17-2 contains an example that illustrates how you can restore a previously created save point in a task flow:

  • view1 contains a button that the end user can click to perform a Save for Later

  • The method call activity calls createSavePoint (see Example 17-3). The createSavePoint method adds a save-point-id. The save-point-id captures everything up to the point in the taskflow where createSavePoint is called.

  • The restore view activity contains an input text field into which a user can enter a save-point-id and click a button to pass the save-point-id to the save point restore activity.

  • savePointRestore1 is a save point restore activity that uses the save-point-id to to restore the application state and data that was captured when the save point was originally created.

Figure 17-2 Save For Later Task Flow

Task flow with save for later capability.

You can access the createSavePoint method under the currentViewPort node under ADF Controller Objects. Instead of calling this method directly, however, you may want to want to create your own method that calls createSavePoint, as shown in Example 17-3. If you do this, you can update the save-point-id with any custom attributes you create on your method.

Example 17-3 Example Custom Method For Creating save-point-id

package viewController;
 
import java.io.Serializable;
import oracle.adf.Controller.ControllerContext;
import oracle.adf.Controller.ViewPortContext;
 
public class SaveForLater implements Serializable
{
 
   public SaveForLater()
 }
 }
 
   public String saveTaskFlow()
  {
    ControllerContext cc = ControllerContext.getInstance();
    if (cc != null)
  {
    SavePointManager mgr = cc.getSavePointManager()           
      if (mgr != null)
 { String id = mgr.createSavePoint();
        System.out.println("Save point is being set "+id);
          }    }
 

The following steps describe adding a call to a custom method to a task flow similar to Figure 17-2. The method creates a save point id similar to Example 17-3.

To add save for later capability to a task flow:

  1. Drag a method call activity from the ADF Task Flow drop-down list of the Component Palette and drop it on the diagram for the ADF bounded task flow.

  2. In the diagram, select the Method Call activity.

  3. In the Common page of the Property Inspector, enter an id for the method, for example, callCreateSavePoint.

  4. In the method field, enter an EL expression for the save point method, for example, #{ControllerContext.getInstance().getSavePointManager.createSavePoint}.

    If you created your own method to call createSavePoint, enter that method name instead.

  5. After adding the method call activity to the diagram, connect it to the other existing activities in the diagram using control flows (see Section 13.2.3, "How to Add Control Flows" for more information). You can specify settings in the adf-config.xml file such as the save point default expiration time and where save points are stored (see Section 17.11.1, "Specifying Save for Later Settings" for more information).

17.5.2 How to Restore Save Points

Use the save point restore activity to restore a previously persisted save point for an application. To identify which save point should be restored, the save point restore activity uses the savepoint that was originally created using the createSavePoint method.

You can obtain a list of the current persisted savepoints using createSavePoint. However, ADF Controller does determine which savepoints to restore. A user must select the savepoint from a list or the application developer select it programmatically. The savepoint id is then passed to a save point restore activity to perform the restore.

To add a save point restore activity to an ADF bounded or unbounded task flow:

  1. In the editor open the bounded or unbounded task flow where you want to add the save point restore activity.

  2. Drag a save point restore activity from the ADF Task Flow drop-down list of the Component Palette and drop it on the diagram for the task flow.

  3. In the diagram, select the save point restore activity.

  4. In the Common page of the Property Inspector, enter an EL expression in the save-point-id field that, when evaluated, specifies the save-point-id that was created when the createSavePoint method was originally called. For example, you could enter #{pageFlowScope.savepoint1}.

17.5.3 How to Use the Save Point Restore Finalizer

When using the save point restore activity, you may need to include application-specific logic that will be performed as part of restoring application state.

Therefore, each task flow definition can specific a finalizer method via a method binding EL expression. The method is invoked after the task flow definition's state has been restored. It performs any necessary logic to ensure the application's state is correct before proceeding with the restore. For example, the application developer must provide restoration logic for validations of a temporal nature.

17.5.4 How to Enable Implicit Save For Later

An implicit save can occur when data is saved automatically because:

  • the session times out due to end user inactivity

  • the user logs out without saving the data

  • the user closes the only browser window, thus logging out of the application

Navigation away from the current application using control flow rules (for example, using a goLink to an external URL) and having unsaved data is a valid condition for creating an implicit breakpoint.

Note:

Implicit save points are created for an application only if you have set enable-implicit-savepoints to true in the adf-config.xml configuration file (see Section 17.11, "Using the adf-config.xml File to Configure ADF Controller" for more information). By default, enable-implicit-savepoints is set to false.

You can specify implicit save for later in a bounded task flow by selecting the critical checkbox for the task flow definition. By default, critical is not selected.

If multiple windows are open when the implicit save point is created, a different save-point-id is created for each browser window. This includes everything from the root view port of the browser window and down. You can use ControllerContext.savePointManager.listSavePointIds to return a list of implicitly created save points.

To enable an implicit save:

  1. In the editor for the ADF bounded task flow, click the Overview tab.

  2. Click Behavior and then select the critical checkbox.

17.5.5 How to Set the Time-to-Live Period

The time-to-live period is the time between when a save point is first created and when it is removed by the Save Point manager. The default is 24 hours. You can specify the default time-to-live and other Save For Later configuration options in the adf-config.xml configuration file. If you specify DATABASE, you must call an API to remove save points. See Section 17.11.1, "Specifying Save for Later Settings" for more information.

You can change the time-to-live period by a call to the setSavePointTimeToLive method. The method syntax is shown in Example 17-4.

Example 17-4 SetSavePointTimeToLive Method Syntax

void setSavePointTimeToLive(long timeInSeconds)

timeInSeconds is set as equal to or less than zero, the default time-to-live is used.

Tip:

You typically will make this method call at the same time a save-point-id is initially created. To do this, you can include the call to setSavePointTimeToLive in the same custom method that you can create to call createSavePoint (see Example 17-3).

17.5.6 What You Need to Know about Using Save for Later with BC4J

To use the Save for Later feature with a BC4J application, you must change the jbo.locking.mode from pessimistic to optimistic. Pessimistic locking, the default setting, causes an old session to lock until the session has timed out. For example, you may run an application, change data without committing changes to the database. When you create a save point and try to restore it, you may get an error.

To set optimistic locking mode:

  1. In the Application Navigator, right-click the BC4J Application Module and choose Configurations.

  2. Click Edit.

  3. Click the Properties tab.

  4. Change jbo.locking.mode from pessimistic to optimistic.

17.6 Creating a Train

A train represents a progression of related activities that guides an end user to the completion of a task. The end user clicks a series of train stops, each stop linking to a particular page. Figure 17-3 shows a train in the Fusion Order Demonstration application that is called when an end user clicks the Self-register link on the User Registration page.

Figure 17-3 Self-registration Train in Fusion Order Demonstration Application

Self-registration Train in Fusion Order Demonstration

This train contains four stops, each corresponding to a JSF page where the end user can enter and review registration information. The train stops are:

Each JSF page in the train contains an ADF Faces Train UI component that enables the user to navigate through the train stops in an order specified in the underlying train model.

Figure 17-4 Train UI Component

Train UI Component

The optional Train Button Bar component (Figure 17-5) contains buttons that provide an additional means to navigate backwards and forwards though the stops. This component can be used in conjunction with the train component to provide multiple ways to navigate through train stops.

Figure 17-5 Train Button Bar UI Component

trainButtonBar UI component.

17.6.1 ADF Bounded Task Flows as Trains

You can create a train based on activities in an ADF bounded task flow that specifies the <train/> element in its metadata. You cannot create a train from activities in an ADF unbounded task flow.

Tip:

You can also create an ADF task flow template that has the <train/> element in its metadata, then create an ADF bounded task flow based on the template.

Each bounded task flow can have a single train only. If the bounded task flow logically includes multiple trains, you must add each train to a separate ADF bounded task flow.

Figure 17-6 displays the bounded task flow that the Fusion Order Demonstration application uses to create the Self-registration train shown in Figure 17-3.

Figure 17-6 customer-registration-task-flow

customer-registration-task-flow

Figure 17-7 contains a simplified detail of the first two train stops in customer-registration-task-flow. In the figure, an icon (two blue circles) identifies each train stop in the train. The dotted line connecting each stop indicates the sequence in which the end user visits them (see Section 17.6.2, "Train Sequences" for more information). Although you can't drag the dotted line to change the sequence, you can right-click on a train stop and choose options to move the train stop forwards or backwards in the sequence. Each train stop is usually a view activity corresponding to a JSF page although you can also add use a task flow call activity as a train stop.

Figure 17-7 Detail of customer-registration-task-flow

Detail of customer-registration-task-flow

The task flow call activity is used to group sets of activities together as a train stop or to call a child train. For example, there are cases when other activities, such as router and method call activities, should be considered part of a train stop along with the corresponding view activity. A method call activity might need to precede a view activity for initialization purposes. When grouped this way, the activities can be performed as a set each time the train stop is visited. See Section Section 17.6.4, "What You May Need to Know About Grouping Activities" for more information.

Branching using router activities and control flow cases is supported on the task flow diagram containing the train as well as in child bounded task flows called from the train. See Section 17.6.7, "What You May Need to Know About Branching" for more information.

17.6.2 Train Sequences

By default, train stops are sequential. A user can select a sequential train stop only after visiting the train stop that is before it in the sequence. A nonsequential train stop can be performed in any order.

As shown in Figure 17-8, a single train can contain both sequential and nonsequential stops. In the figure, First Stop is the current train stop. Second Step is sequential because the user can click it only after visiting First Step. Third Step is nonsequential because it can be clicked immediately after the user visits First Step without also having to visit Second Step.

When First Step is the current stop, the end user cannot click the Fifth and Sixth Steps 6, indicating that they are sequential.

Figure 17-8 Train with Sequential and NonSequential Stops

Sequential and nonsequential train stops.

You can set the sequential option on the view activity (or task flow call activity) for each train stop to specify whether it has sequential or nonsequential behavior. The sequential option contains an EL expression that evaluates end user input or some other factor, for example, #{myTrainModel.isSequential}. When the EL Expression evaluates to true, the train stop behaves as sequential. When it evaluates to false, the train stop behaves as nonsequential.

In addition, you can alter the overall train sequence by skipping over individual train stops. The skip option on the activity corresponding to the train stop uses an EL expression that evaluates end user input or some other factor to determine whether to skip over the train stop. If it evaluates to true, the train stop appears disabled and will be passed over. The end user is taken to the next enabled stop in the train. In addition, the train stop will be skipped if the end user clicks a Next or Previous button.

Note:

If you want the train to execute by default at some train stop other than the first one, use the skip option. For example, if you want the train to begin executing at train stop 3, specify skip on train stops 1 and 2. This is a better practice than marking a view activity associated with a train stop as the default activity for the ADF bounded task flow, which can cause unpredictable results. For more information, see Section 13.4, "Designating a Default Activity in an ADF Bounded Task Flow".

17.6.3 How to Create a Train

To use an ADF bounded task flow as a train, its metatdata must contain the </train> element in its task flow definition. There are several ways to include this element in the metadata:

  • Select the Create Train checkbox in the Create ADF Task Flow dialog box (see Section 13.2, "Creating Task Flows" for more information).

  • Select the Create Train checkbox in the Create ADF Task Flow Template dialog box, then use the template to create a new ADF bounded task flow (see Section 17.8, "Creating an ADF Task Flow Template" for more information).t

  • Right-click on an existing bounded task flow diagram in the editor and choose Train > Create Train.

  • Open an existing ADF bounded task flow in the editor, click the Overview tab, click Behavior, and select the Train checkbox

To create a train:

  1. In the editor, open an ADF bounded task flow that is usable as a train.

    You must include the <train/> element in the ADF bounded task flow's metadata by following one of the methods described above.

  2. Drag each view activity or JSF page you want to include in the train from the Application Navigator to the ADF bounded task flow diagram.

    • If you drag a JSF page, JDeveloper automatically adds a view activity to the diagram.

    • If you drag a view activity to the ADF bounded task flow diagram, you can double- click it later to create a new JSF page.

    Tip:

    Don't worry adding pages or view activities to the diagram in a particular order. You can adjust the train sequence later.
  3. To rearrange the order of train stops, right-click its corresponding activity in the diagram. Choose Train, and then choose a menu item to move the train stop within the sequence, for example, Move Forward, Move Backward, etc.

  4. By default, trains stops are sequential. You can optionally define whether the train stop behaves nonsequentially.

    1. In the bounded task flow diagram, select the activity associated with the nonsequential train stop.

    2. In the Property Inspector for the activity, click Train Stop.

    3. In the sequential field, enter an EL expression, for example, #{myTrainModel.isSequential}.

      You can also specify a literal value, for example, true.

      If the EL expression evaluates to true, the train stop will be sequential. If false, the train stop will be nonsequential.

  5. By default, a train stop will not be skipped. You can optionally designate that the train stop can be skipped based on the result of an EL expression.

    1. In the ADF bounded task flow diagram, select the activity associated with the nonsequential train stop.

    2. In the Property Inspector, click Train Stop.

    3. In the skip field, enter an EL expression, for example, #{myTrainModel.shouldSkip}.

      If the EL expression evaluates to true, the train stop will be skipped. If false, the train stop will be not be skipped.

  6. In the diagram, double-click each view activity that is being used as a train stop.

    Double-clicking the view activity opens a dialog to create a new JSF page. If a JSF page is already associated with the view activity, the existing page displays.

  7. Open the JSF page in the editor.

  8. For each JSF page in the train, select a Train and, optionally, a Train Button Bar UI component from the Common Components section of the ADF Faces page of the Component Palette. Drag the UI component onto the JSF page.

    The Train and Train Button Bar UI components are not automatically added to pages and page fragments corresponding to the view activities within a task flow definition for a train. You must add them manually to each page or page fragment. You can also add them using a page template.

    After you add the components to the page, they are automatically bound to the train model. For more information about creating a train model, see the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework for more information.

17.6.4 What You May Need to Know About Grouping Activities

Activities such as routers and method calls can be grouped with a view activity to form a single train stop. In the customer registration bounded task flow (Figure 17-6 above), the createAddress method call activity and the addressDetails view activity are grouped with the defineAddress view activity to create the second stop in the train. The activities are performed as a set each time the train stop is visited. createAddress validates user input on the Address page and defineAddress is an optional page where the end user can enter additional address information. Because the page is optional and is accessed using a link on the Address page, it is not included in the bounded task flow as a separate train stop. Instead, it is grouped as one of the activities for the createAddress train stop.

Note:

The recommended approach for grouping a set of activities to form a train stop is to use a child ADF bounded task flow (see Section 17.6.5, "What You May Need to Know About Grouping Activities in Child Task Flows"). The advantage of this approach is that all activities in the group are always performed together regardless of whether the train stop is being visited for the first time or on later returns.

If you don't use a child ADF bounded task flow, all activities from the leading non-view activity through the next view activity will be considered part of the train stop's execution.

Although the recommended approach is to group a set of activities for a train stop within a child bounded task flow, you can provide the same functionality without a call to a child bounded task flow. Instead you can group the activities on the parent bounded task flow, as shown in Figure 17-9 below. All activities leading from the first non-view activity through the next view activity are considered part of the implied train stop's execution.

To group activities without a child bounded task flow, you must ensure that:

  • all non-view and non-task flow call activities for the train stop, such as routers and methods calls, should follow the view or task flow call activity being used as the train stop.

    This associates the activities with the train stop and not with the previous stop in the train.

  • a wildcard control flow leads to first activity of the train stop.

    You must specify a value for from-outcome (for example gotoCollateSurveryAnswers) on the control flow leading from the wildcard control flow. This value must match the value you specify for the train outcome on the view activity that is used as the train stop.

    The wildcard control flow ensures that if an end user returns to a previously visited trainstop, all activities will be performed beginning with the activity the wildcard control flow points to.

Figure 17-9 Grouping Activities Without Using a Task Flow Call Activity

Grouping activities without a task flow call

In Figure 17-9 above, the SurveyPage2 train stop consists of the following group of activities that execute in the following order:

  1. Wildcard control flow leading to first activity of the train stop, CollateSurveyAnswers.

    Note:

    The train stop outcome element is used only if an activity such as a method call activity or router is placed prior to the view activity train stop. The element allows you to specify a custom outcome that results in navigation to the train stop.
  2. Method call to CollateSurveyAnswers method

  3. SurveyPage2 view

17.6.5 What You May Need to Know About Grouping Activities in Child Task Flows

You can also group related activities along with a corresponding view activity in a child ADF bounded task flow. Then you can designate a task flow call activity as train stop in the train (Section 14.6, "Using Task Flow Call Activities" for more information). The task flow call activity calls the child ADF bounded task flow. The group of activities are always performed together regardless of whether the train stop is being visited for the first time or on later returns.

Best practice:

When grouping activities in a called child bounded task flow, non-view activities such as routers and methods calls typically precede the view activity in the control flow. You can include multiple view activities within the child bounded task flow, although in most cases there will be only one.

To group activities in the called child bounded task flow, you must ensure that:

  • All non-view activities for the train stop, such as routers and methods calls, precede the view activity in the control flow of the child bounded task flow.

  • the child task flow contains a single view activity, unless the view activities are dialogs or helper pages originating from the main train stop view activity.

Figure 17-10 shows the SurveyTaskFlow train stop, a task flow call activity that calls a child bounded task flow.

Figure 17-10 Task Flow Call Activity Train Stop

Task flow call activty train stop

The child bounded task flow is shown in Figure 17-19

Figure 17-11 Called Child Bounded Task Flow

Called child bounded task flowj

All of the activities in the child bounded task flow are performed together every time the SurveyTaskFlow train is visited, regardless if the end user is visiting the first time or later.

If you use a child ADF bounded task flow to group a set of activities, you must add a a task flow return activity to the child task flow. The task flow return activity leads back to the parent bounded task flow, thus continuing the train. The task flow return activity should specify a value in outcome, for example, done, that will be used when returning to the parent train. In addition, you must manually add a control flow to the parent task flow that will be used to continue control flow within the train after returning from the child task flow.

As shown in Figure 17-10 and Figure 17-11 above, the value specified in the from-outcome for the control flow case (done) matches the task flow return activity outcome value.

17.6.6 What You May Need To Know About Using Child Trains

A train can use a task flow call activity as a train stop to invoke a child ADF bounded task flow representing another train. The child ADF bounded task flow must be created as its own train (must have the <train/> element in its metadata) and contain its own train stops. There is no limit to the depth of calls that are allowed to child trains.

17.6.7 What You May Need to Know About Branching

You can branch using router activities and control flow cases within a group of activities that are grouped to represent a single train stop, for example, the wildcard control flow rule router, and methods calls under step 2 in Figure 17-12.

You cannot branch between the activities that represent each train stop in a train. For example, you can not branch between steps 1, 2, and 3 in Figure 17-12.

Figure 17-12 Branching within Grouped Activities for a Single Train Stop

Branfching within grouped activites

17.7 Running an ADF Bounded Task Flow as a Modal Dialog

An executing application can link to a page to get information from the user and then return to the original page to use that information. You can optionally display the page in a modal dialog that has to be closed before the end user can return to using the parent application.

Note:

An ADF unbounded task flow must run in a secondary window, not a modal dialog.

ADF bounded task flows can run in ADF regions. The ADF region can be in an af:popup UI component.

Figure 17-13 Source Task Flow

A source task flow.

Suppose you created a task flow containing a view and task flow call activity similar to Figure 17-13. When a user clicks a button in the launch_page view activity, the bounded task flow associated with calltoTarget executes.

Figure 17-14 launch_page

launch_page

On launch_page, the outcome identified by a button's action property, callTarget passes control to the task flow call activity. If you select the run-as-dialog option on the task flow call activity, all of the pages within the called ADF bounded task flow execute within a modal dialog.

The value that the user enters in the launch_page can be used by the called task flow. For example, you could add a page on the called bounded task flow that displays the value in an output text component. The bounded task flow running as modal dialog can also pass values back to the caller.

Note:

If your application uses ADF Controller features (for example, ADF task flows), specifying dialog: syntax in navigation rules within faces-config.xml is not supported.

However, you can use the dialog: syntax in the control flow rules that you specify in the adfc-config.xml file.

For example, you can specify the following in adfc-config.xml:

<?xml version="1.0" encoding="windows-1252" ?> 
  <adfc-config xmlns="http://xmlns.oracle.com/adf/Controller"> 
    <view id="view1"
        <page>/view1.jspx</page> 
    </view>
    <view id="dialog"> 
       <page>/dialog/untitled1.jspx</page> 
   </view> 
   <control-flow-rule> 
        <from-activity-id>test</from-activity-id> 
        <control-flow-case> 
          <from-outcome>dialog:test</from-outcome
          <to-activity-id>dialog</to-activity-id>
         </control-flow-case> 
</adfc-config>

17.7.1 How to Run an ADF Bounded Task Flow in a Modal Dialog

Before you begin, create a source that contains the activities shown in Figure 17-13. The view in the source task flow should be associated with a page containing an ADF Faces button and an input text field, similar to launch_page in Figure 17-14.

To run an ADF bounded task flow as a modal dialog box:

  1. In the Application Navigator, double-click the page that will launch the modal dialog.

  2. In the editor, select the button component on the page

  3. On the Common page of the Property Inspector, expand the Button Action section.

  4. In the Action field, enter an action, for example, calltoTarget.

    The action must match the from-outcome on the control flow case leading to the task flow call activity. In Figure 17-13, this is calltoTarget.

  5. In the UseWindow drop-down list, select true.

    Setting useWindow to true launches the target in a popup dialog.

  6. In the source task flow diagram, select the task flow call activity.

  7. In the Property Inspector, click Behavior and expand the Run as Dialog section.

  8. In the run-as-dialog drop-down list, select true.

  9. In the Application Navigator, double-click the page (launch_page) that will launch the modal dialog.

17.7.2 How to Pass Back a Return Value

The ADF bounded task flow can optionally return a value to the calling page when the modal dialog is dismissed. The return value can be displayed in an input UI component on the calling page.

The launching command button must specify a return listener. The return listener is a method binding for a method with one argument, a return event. The return listener takes the value specified in the returnEvent and sets it on the input component.The input UI component should accept the return value of the command button by specifying a backing bean and setting its partialTriggers attribute to the id of the launching command button (see Using Input Components and Defining Forms in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework for more information). The backing bean containing the return listener should be registered in adfc-config.xml.

The target bounded task flow in the example contains a single view activity associated with a page that contains an output text component. The source task flow passes the value in the input text field as a parameter to the target task flow (for more information, see Section 15.2, "Passing Parameters to an ADF Bounded Task Flow").

In addition, the target task flow should specify a return value definition. To return a value, you must specify:

  • Return value definition on the called bounded task flow. This specifies where the return value is to be taken from upon exit of the called bounded task flow.

  • Return values on the task flow call activity in the calling task flow. These specify where the calling task flow can find return values (for more information, see Section 15.4, "Specifying Return Values").

Before you begin, follow the steps described in Section 17.7.1, "How to Run an ADF Bounded Task Flow in a Modal Dialog".

To specify a return value:

  1. In the source task flow diagram, select the task flow call activity.

  2. In the Property Inspector, click Behavior and expand the Run as Dialog section.

  3. In the run-as-dialog drop-down list, select true.

  4. In the Property Inspector, enter a dialog-return-value, for example, returnvalue.

    The dialog-return-value must match the name of the return value definition you specified for the target bounded task flow. If you have not already a specified return value definition on the called task flow, see Section 15.4, "Specifying Return Values" for more information.

  5. In the Application Navigator, double-click the page that will launch the modal dialog.

  6. In the editor, select the Input UI component on the page.

  7. In the Property Inspector, click Behavior.

  8. In the PartialTriggers field, enter an EL expression for a partial trigger, for example, #{pageFlowScope.backingBean.gotoModalDialog}.

    The input component on the launch_page can accept the return value of the command button by specifying a backing bean and setting its partialTriggers attribute to the id of the launching command button. In the example EL expression above, backingBean is the name of a backing bean and gotoModalDialog is the id of the launching command button shown in Figure 17-14.

    For information on how to create backing beans, see the Using Input Components and Defining Forms in the Oracle ADF Faces Developer's Guide for more information.

  9. In the Property Inspector for the button UI component, click Behavior.

  10. Expand the Secondary Window

  11. In the ReturnListener field, enter an EL expression that specifies a reference to a return listener method in the page's backing bean, for example, #{pageBean.listenerMethod}.

    The return listener method will be used to process a return event that is generated when the modal dialog is dismissed.

17.8 Creating an ADF Task Flow Template

You can create an ADF task flow template that other developers can use as a starting point when creating new ADF bounded task flows.

Note:

You cannot use an ADF task flow template as the basis for creating a new ADF unbounded task flow.

The task flow template enables reuse because any ADF bounded task flow based on it has the same set of activities, control flows, input parameters, and managed bean definitions that the template contains. In addition, you can specify that changes to the template are automatically propagated to any task flow or template that is created based on the template.

For example, suppose you have set up an activity to be used as an exception handler for an ADF bounded task flow, such as a view activity associated with a page for global exception handling. Or, the exception handler might be set up to handle exceptions typically expected to occur in a task flow. If you expect multiple ADF bounded task flows to rely on the same error handler, you might consider adding the error handler to a task flow template. New task flows created based on the template automatically have the error handling activity added to the template. See Section 17.4, "Handling Exceptions" for more information.

You can base an ADF task flow template on an existing ADF task flow template. You can also refactor an existing ADF bounded task flow to create a new task flow template (for more information, see Section 13.7.3, "How to Convert ADF Bounded Task Flows").

If you select the Update the Task Flow When the Template Changes checkbox in the Create ADF Task Flow or Create ADF Task Flow Template dialog, the template will be reused by reference. Any changes you make to the template will be propagated to any ADF bounded task flow or ADF task flow template based on it.

17.8.1 Copying and Referencing an ADF Task Flow Template

There are two methods for reusing a ADF task flow templates.

  • Reuse by copy

    Deselect the Update the task flow when the template changes checkbox when creating a new ADF bounded task flow, as shown in Figure 17-15. If you deselect the checkbox, the ADF bounded task flow is independent of the template. Changes to the template are not propagated to the ADF bounded task flow.

    For example, if you add View activities associated with JSF pages to the template, the new ADF bounded task flow will display the Views, any control flows between them, and will retain the View associations with JSF pages. If you add a train on an ADF task flow template, any ADF bounded task flow created from it contains page navigation for the train.

  • Reuse by reference

    Select the Update the task flow when the template changes checkbox when creating a new ADF bounded task flow, as show in Figure 17-15, or when creating a new ADF task flow template. Changes to the parent ADF task flow template propagate to any ADF bounded task flow or template based on it.

    You can change, update, or disassociate the parent task flow template of a child ADF bounded task flow or task flow template at any point during development of the child.

At runtime, the contents of a child bounded task flow or a child template reused by reference are combined additively with the contents of the parent template. Any collision between the parent template and child task flow or child template are won by the child. For example, suppose you created a parent task flow template containing a train, and then created a child ADF bounded task flow based on the parent template. Later, you unchecked the Train checkbox on the Behavior page of the task flow definition Overview tab. The difference in how the Train checkbox is set for the parent template and the child task flow is a collision.

Table 17-2 describes the specific combination algorithm used for each element. As shown in the table, in the event of a collision between train settings, the child task flow overrides the parent task flow template.

Table 17-2 Collision Resolution between Parent Template and Children

Task Flow Definition Metadata Combination Algorithm

Default activity

Child bounded task flow or child task flow template overrides parent task flow template.

Transaction

Child bounded task flow or child task flow template overrides parent task flow template as an entire block of metadata, including all subordinate elements.

Task flow reentry

Child bounded task flow or child task flow template overrides parent task flow template. as an entire block of metadata, including all subordinate elements.

Control flow rules

Combination algorithm occurs at the control flow case level, not the control flow rule level. Control flow cases fall into the following categories:

  • Both from action and from outcome specified

  • Only from action specified

  • Only from outcome specified

  • Neither from action nor from outcome specified

Each of these categories are merged additively. The child task flow definition or template overrides parent task flow template for identical matches within each of the four categories.

Input parameter definitions

Child bounded task flow or child task flow template overrides parent task flow template for identical input parameter definition names.

Return value definitions

Child bounded task flow or child task flow template overrides parent task flow template for identical return value definition names.

Activities

Child bounded task flow or child task flow template overrides parent task flow template for identical activity ids.

Managed beans

Child bounded task flow or child task flow template overrides parent task flow template for identical managed bean names.

Initializer

Child bounded task flow or child task flow template overrides parent task flow template.

Finalizer

Child bounded task flow or child task flow template overrides parent task flow template.

Critical

Child bounded task flow or child task flow template overrides parent task flow template.

Use page fragments

Child bounded task flow or child task flow template overrides parent task flow template.

Exception handler

Child bounded task flow or child task flow template overrides parent task flow template.

Security - permission

Child bounded task flow or child task flow template overrides parent task flow template.

Privilege maps are additive. Child bounded task flow or child task flow template overrides parent task flow template for identical privilege map operations.

Security - transport guarantee

Child bounded task flow or child task flow template overrides parent task flow template.

Train

Child bounded task flow or child task flow template overrides parent task flow template.


Validations at both design time and runtime verify that the resulting parent - child extension hierarchy doesn't involve cycles of the same ADF task flow template.

17.8.2 Creating an ADF Task Flow Template from Another Task Flow

The process for creating a new ADF task flow template from an existing template is similar to creating an ADF bounded task flow based on a template (see Section 13.2, "Creating Task Flows" for more information).

17.8.3 How to Use an ADF Task Flow Template

After you create an ADF task flow template, you can use it as the basis for creating a new ADF bounded task flow or a new task flow template. As shown in Figure 17-15, the Create ADF Task Flow dialog has fields for creating an ADF bounded task flow based on the template file name and the id. You must specify both the file name and id of the template. These fields are available only if you select the Create as Bounded Task Flow checkbox.

Figure 17-15 Create ADF Task Flow Dialog

Create ADF Task Flow dialog.

You can base a new template on an existing template. The Create ADF Task Flow Template dialog box contains fields for creating an ADF task flow template based on the file name and the template id of an existing task flow template.

You cannot run an ADF task flow template on its own. See Section 13.5, "Running ADF Task Flows" for more information.

17.8.4 How to Create an ADF Task Flow Template

The process for creating a new ADF task flow template is similar to creating an ADF bounded task flow. This section describes how to create a new ADF task flow template from scratch. You can also convert an existing ADF bounded task flow to a task flow template and vice versa (see Section 17.8.2, "Creating an ADF Task Flow Template from Another Task Flow" for more information).

To create an ADF task flow template:

  1. In the Application Navigation, right-click the project where you want to create the task flow and choose New.

  2. In the New Gallery, open the Web Tier node.

  3. Click JSF and then click ADF Task Flow Template.

  4. The value in File Name is used to name the XML source file for the ADF task flow template you are creating. The source file includes the activities and control flow rules that are in the task flow template. The default name for the XML source file is task-flow-template.xml.

  5. In the Create ADF Task Flow Template dialog, the Create with Page Fragments checkbox is selected by default. If you expect that an ADF bounded task flow based on the template will be used as an ADF region, select this option.

    If you want to add JSF pages instead of JSF page fragments to the task flow template, deselect the checkbox.

  6. Click OK.

    A diagram for the task flow template automatically opens in the editor.

  7. You can add activities, control flows, and other items to the template.

    Anything you can add to an ADF bounded task flow can be added to the ADF task flow template.

  8. When you are finished, save your work.

    The template will be available for use when you create an ADF bounded task flow or ADF task flow template.

17.8.5 What Happens When You Create an ADF Task Flow Template

As shown in Example 17-5, an XML file is created each time you create a new ADF task flow template using JDeveloper. You can find the XML file in the Application Navigator in the location that you specified in the Directory field of the Create ADF Task Flow Template dialog, for example,.../WEB-INF.

The contents of the XML source file for the ADF task flow template can be similar to those of an ADF bounded task flow definition. One difference is the inclusion of the <task-flow-template> tag.

Example 17-5 ADF task flow template source file

<?xml version="1.0" encoding="windows-1252" ?>
<adfc-config xmlns="http://xmlns.oracle.com/adf/Controller">
  <task-flow-template id="task-flow-template">
     <default-activity>view1</default-activity>
     <view id="view1">view1.jsff</view>
  </task-flow-template>
</adfc-config>

17.8.6 What You Need to Know About ADF Task Flow Templates That Use Bindings

If you use an ADF task flow template that contains bindings, you must change the component IDs of ADF task flows based on the ADF task flow template. This ensures that the IDs are unique. ADF task flows generated from the template use the same IDs as the template ID. This may cause an exception at runtime.

For more information, see Section 18.2.1, "How to Use ADF Data Binding in ADF Page Templates".

17.9 Creating a Page Hierarchy

Note:

This section describes creating a page hierarchy. If you follow the steps below, JDeveloper automatically generates the metadata required to create the hierarchy.

You also have the option of building the page hierarchy yourself using your own XML Menu model metadata. For more information, see the Web User Interface Developer's Guide for Oracle Application Development Framework.

The section in the developer's guide also contains detailed information about the XML menu model metadata.

You can create an application of related JSF pages that are organized in a tree-like hierarchy. End users access information on the pages by navigating a path of links. Figure 17-16 shows a sample page hierarchy.

Figure 17-16 Page Hierarchy

Page hierarchy.

To navigate, an end user clicks links on each page to drill down or up to another level of the hierarchy. For example, clicking Human Resources on the Application Suite Home page displays the page hierarchy shown in Figure 17-16 above. Clicking the link on the Benefits tab displays the page hierarchy shown below in Figure 17-17.

Figure 17-17 Benefits Page

Benefits page.

The user can click links on the Benefits page to display other pages, for example, the Medical, Dental or Vision pages. The breadcrumbs on each page indicate where the current page fits in the hierarchy. The user can click each node in a breadcrumb to navigate to other pages in the hierarchy. The bold tab labels match the path to the current page shown the breadcrumbs.

You can use ADF Controller features in conjunction with XML Menu Model to build the page hierarchy. If you use this method, the following is generated automatically for you:

17.9.1 XML Menu Model

The XML menu model represents navigation for a page hierarchy in XML format. In the XML menu model metadata, a page hierarchy is described within the menu element, which is the root element of the file. Every XML menu model metadata file is required to have a menu element. Only one menu element is allowed.

A hierarchy is comprised of nodes. Each node corresponds to a page. The menu element can contain elements for the following nodes:

  • groupNode: Contains one or more child nodes to navigate to indirectly. It must reference the id of at least one of its child nodes, which can be either another group node or an item node.

  • itemNode: Specifies a node that performs navigation upon user selection.

  • sharedNode: References another XML menu. A sharedNode is not a true node; it does not perform navigation nor does it render anything on its own. It is simply an include mechanism. Use a sharedNode to link or include various menus into a larger hierarchy.

The Benefits page in Figure 17-17 above, for example, contains a group node called Benefits and three item nodes called Medical, Dental and Vision. The Benefits group node references its child Medical item node. Clicking on the Benefits menu item tab actually results in the Medical page being displayed.

When you create the pages in your hierarchy, you don't have to create any navigation links. For example, the Medical, Dental and Vision links are automatically built on the Benefits page if you make the first the three links item nodes and Benefits a group node.

17.9.2 How to Create a Page Hierarchy

You also don't need to create the nodes in the metadata file for your page hierarchy. JDeveloper does that for you. All you need to do is organize the nodes in the hierarchy.

To create a page hierarchy, you first divide the nodes into menus. Figure 17-18 shows the division of the Human Resources page hierarchy into menus:

Note:

It is possible to create the entire menu hierarchy in one menu model. However, breaking a menu hierarchy into submenus makes maintenance easier. In addition, breaking the menu hierarchy into smaller submenu models enables each separate development organization to develop its own menu. These separate menus can later be combined using shared nodes to create the complete menu hierarchy.
  • The top level menu contains the Fusion Application Suite Home page. This is the root parent page and contains a single tab that links to the Human Resources sub menu model.

    In this menu, the Home page is represented as an item node and the Human Resources page as a shared node.

  • The Human Resources' four tabs link to child Payroll, Time, Labor, and Benefits pages.

    In this menu, Human Resources is a group node referring to its child Payroll item node, two additional item nodes for the Time and Labor pages, and a Benefits shared node that includes the Benefits submenu model.

  • The Benefits node is a page that contains links to the Medical, Dental and Vision pages.

    In this menu, Benefits page is a group node referring to its child Medical item node, and two additional item nodes for the Dental and Vision pages.

Figure 17-18 Menu Hierarchy

Menu hierarchy.

To create a page hierarchy:

  1. Create the pages you will use in your menu hierarchy. See Section 18.3, "Creating a Web Page" for more information.

    Create one page for each node in the hierarchy.

    Note:

    You are not required to create your pages first. Instead, you can wait until later in the process, for example, after you've organized the page hierarchy following the steps below.
  2. For each menu that will be in the final page hierarchy create an XML source files by deselecting the Create as Bounded Task Flow checkbox in the Create ADF Task Flow dialog. JDeveloper will combine these XML source files into a single ADF unbounded task flow. See Section 13.2.1, "How to Create an ADF Task Flow" for more information.

    For example, Figure 17-18 contains three menus:

    • a top level or root menu that contains the Fusion Application Suite Home page. the Human Resources menu the Benefits menu

    Therefore you should create three XML source files, for example:

    • adfc-config.xml source file (always) corresponds to the root menu

    • adfc-hr-config.xml source file corresponds to the Human resources menu

    • adfc-benefits-config.xml source file corresponds to the Benefits menu

    Tip:

    Prefix all of your source file names for the unbounded task flows with adfc_. This helps to identify the file as the source for an unbounded task flow, as opposed to a bounded task flow definition.
  3. In the Application Navigator, double-click each source file to open it in the editor.

  4. Add view activities to each source file that correspond to each menu node in the appropriate menu.

    For example, the Benefits menu will contain one group node (benefits) and three item nodes (medical, dental and vision). Therefore, add four view activities to the source for the Benefits menu. Four view activities in unbounded task flow.

    Note:

    For menus that will include other menus using shared nodes, do not create views for the shared nodes. For example the HR menu will have a node at the end called Benefits that will include the Benefits menu using a shared node. Because a shared node is not really a node, there is no need to create a view for the Benefits page. This view has already been put in the XML source file associated with Benefits, adfc-benefits-config.xml.Similarly, the Fusion Application Home Page menu includes the Human Resources menu at the end by using a shared node. Therefore, there is no need to create a view for the Human Resources page in adfc-config.xml. It is already in the XML source file associated with Human Resources, adfc-hr-config.xml.
  5. Associate the pages you created for the hierarchy with the views.

    The easiest way to do this is to drag the page from the Application Navigation and drop it onto its corresponding view activity in the task flow diagram.

  6. In the Application Navigator, right-click each XML source file included in the page hierarchy and choose Create ADF Menu.

    For example, you could begin by right-clicking on adfc_benefits.xml. This bottom up method is the best for this scenario because the parent menus include the submenus (via shared nodes). It is better if the submenus are created first.

  7. In the Create ADF Menu Model dialog, enter a File Name for the menu XML file that will be generated and a Directory where it will be located.

  8. Click OK.

    The XML source file is updated with the control flows and managed beans used to navigate. In general, you don't have to change anything in this source file. However, you can use ADF Controller features to update any of this information. You might change the from-outcome default values (such as __benefits_adfMenu_action__) given to each of the control flow cases in the diagram.

    Figure 17-19 Updated Unbounded Task Flow Diagram

    Updated unbounded task flow diagram.

    In addition, a new menu XML file is created. Keep in mind that the menu XML file is different from the XML source file for the unbounded task flow.

  9. In the Application Navigator, scroll down to the menu XML file and select it.

    The file will be in the Application Navigator at the location you selected in the Directory field of the Create ADF Menu Model dialog.

    In the Structure window, all of the views that are in the unbounded task flow now have corresponding item nodes in the menu XML file. All item nodes are at the same level. They are all siblings and none is a parent of any other node by default.

  10. Create a hierarchy of group and child nodes.

    The group node must refer to at least one child node. For example, before converting the Benefits node from an item node to a group node, you must identify its child nodes (Medical, Dental, and Vision).

    1. In the Structure window, drag and drop each child menu onto its parent.

    2. Right-click on the parent node (for example, Benefits) and choose Convert.

    3. In the Convert dialog choose groupNode and click OK.

    4. In the id field, enter a new identifier or accept the default.

      The id must be unique among all of the nodes in all of the menu models. It is good practice to specify an id that identifies the node. For example, if you change the Benefits node to a group node, you can update its default id, __benefits_itemNode__, to __benefits_groupNode__.

    5. In the idref field, enter the id of one of the other nodes in the menu, for example, __medical_itemNode__.

      The value you enter can be an id of a child that is a group node or an item node.

    6. Enter or change the existing default value in the label field to match what you want to display. For example, you might change ___benefits_label__ to Benefits.

    7. Accept the rest of the default values in the fields and click Finish.

    8. The Confirm Convert dialog asks if you want to delete the action and focusViewID attributes on the groupNode element. Since group nodes do not use these attributes, always click OK.

  11. If you selected sharedNode on the Convert dialog:

    1. In the ref field, enter an EL expression that references another XML menu file, for example, #{benefits_menu}.

      benefits_menu is a <managed-bean-name> property of the managed bean that defines the menu model for the Benefits menu. You can find this managed at the bottom of the XML source file for the benefits_menu.

      For example, the HR menu contains four item nodes. One of the item nodes, Benefits, should include another menu called benefits_menu. In the Structure window for the HR menu file, you would select the Benefits item node and choose Convert > sharedNode. In the ref field, you could enter #{benefits_menu}.

    2. Click OK.

      Now you have included the HR menu into the root menu.

    3. Update all of your menu nodes in all menu XML files. The default generated labels are probably not what you want in your application.

  12. You can also add a new node to a menu instead of converting an existing one.

    1. In the Structure window scroll to the location where you want add the node.

    2. Right click and choose an Insert option.

    3. Choose itemNode, groupNode or sharedNode.

  13. To run the finished page hierarchy:

    1. In the Application Navigator, right-click on your project node and choose Build Project Working Set.

    2. In the Application, Navigator, scroll to the unbounded task flow containing the root menu. This should always be called adfc_config.xml.

    3. If everything compiles without errors, right-click and choose Run. For more information, see Section 13.5.5, "How to Run an ADF Unbounded Task Flow".

      Note:

      If your page hierarchy is based on more than one unbounded task flow in the same project, ensure that each additional unbounded task flow configuration file is listed as a <metadata-resources> element in the top-level adfc_config.xml file for the hierarchy. For more information, see Section 17.10, "How to Specify Bootstrap Configuration Files".

17.10 How to Specify Bootstrap Configuration Files

The top level XML source files in an application are known as the application's bootstrap configuration files. The content and loading mechanism for each file mimics faces-config.xml, the XML source file used in JSF navigation. When you create a new ADF unbounded task flow, JDeveloper automatically adds an entry into adfc-config.xml to include the task flow it in the bootstrap list.

Bootstrap XML source files are loaded when an application is first started. The files can contain:

The main bootstrap XML source file is usually named adfc-config.xml. A single web application can have multiple top level XML source files, which are loaded when application is first started. Although the bootstrap XML source files can be implemented as separate physical files, they are all considered the same logical file at runtime.

You can add additional bootstrap XML source files in the Metadata Resources list. To access the list, click the Overview tab for adfc-config.xml or some other bootstrap configuration file, then click Metadata Resources.

Note:

It is a best practice to specify metadata resources within the adfc-config.xml file or any of the bootstrap configuration files referenced within adfc-config.xml.

17.11 Using the adf-config.xml File to Configure ADF Controller

The central configuration file for all of ADF is adf-config.xml. This file contains sections that configure different ADF components, for example, ADF Controller behavior such as save for later.

17.11.1 Specifying Save for Later Settings

You can specify save for later settings in the adf-config.xml file such as whether implicit save points can be created in the application, as shown in Table 17-3.

Table 17-3 Save For Later Configuration Properties

Property Description

savepoint-datasource

JNDI name of the data source, for example, java:comp/env/jdbc/Connection1DS

The value for this property is different from the JDeveloper Database Connection name. JDeveloper datasources typically append a "DS" on the end of the database connection name.

enable-implicit-savepoints

When set to true, implicit save points can be created for the application. See Section 17.5.1, "How to Add Save For Later Capabilities" for information about creating a save point.

The default setting for this property is false.


17.11.2 Validating ADF Controller Metadata

Basic validation is performed when ADF Controller retrieves metadata. The most serious errors, for example, a task flow that is missing a default activity, result in parsing exceptions.

The enable-grammar-validation setting in adf-config.xml allows you to validate the grammar in ADF Controller metadata before deploying an application. When enable-grammar-validation is set to true, ADF Controller metadata is validated against ADF Controller XSDs. For example, invalid characters in ADF Controller metadata such as a slash (/) in a view activity id are flagged as exceptions.

By default, enable-grammar-validation is set to false. For performance reasons, it should be set to true only during application development or when troubleshooting an application.

17.11.3 Searching for adf-config.xml

ADFConfigFactory first searches for the adf_config.xml file in META-INF. The first file it finds in this location is used.

The integrated development environment (IDE) creates adf-config.xml in the location <application root>/.adf/META-INF/adf-config.xml.By default, when the application runs or a.war file is built, this location is included. However, if you create an adf-config.xml file and put it in <project root>/META-INF/adf-config.xml, you cannot guarantee it will be used. If there is another adf-config.xml, then it will be used instead. The adf-config.xml file in WEB-INF is parsed but only if the filter oracle.adf.share.http.ServletADFFilter is installed. This adf-config.xml file is merged on top of the one found in META-INF. In this way, it is possible to have both an application-level adf-config.xml file and a project-level adf-config.xml configuration file.

17.11.4 Replicating Memory Scopes in a Server-Cluster Environment

Typically, in an application that runs in a clustered environment, a portion of the application's state is serialized and copied to another server or a data store at the end of each request so that the state is available to other servers in the cluster.

When you are designing an application to run in a clustered environment, you must:

  • Ensure all managed beans with a lifespan longer than one request are serializable (that is, they implement the java.io.Serializable interface). Specifically, beans stored in sessionScope, pageFlowScope, and viewScope need to be serializable.

  • Make sure that the ADF framework is aware of changes to managed beans stored in ADF scopes (viewScope and pageFlowScope).

When a value within a managed bean in either viewScope or pageFlowScope is modified, the application needs to notify ADF framework so it can ensure the bean's new value get replicated.

In Example 17-6, an attribute of an object in viewScope is being modified.

Example 17-6 Code that Modifies an Object in viewScope

Map<String, Object> viewScope =
    AdfFacesContext.getCurrentInstance().getViewScope();
MyObject obj = (MyObject)viewScope.get("myObjectName");
Obj.setFoo("newValue");

Without additional code, the ADF framework will be unaware of this change and will not know that a new value needs to be replicated within the cluster. To inform the ADF framework that an object in an ADF scope has been modified and that replication is needed, use the markScopeDirty() method similar to what is shown in Example 17-7. The markScopeDirty() method accepts only viewScope and pageFlowScope as parameters.

Example 17-7 Additional Code to Notify the ADF Framework of Changes to an Object

ControllerContext ctx = ControllerContext.getInstance();
        ctx.markScopeDirty(viewScope);

This code is needed for any request that modifies an existing object in one of the ADF scopes. It is not necessary to notify the ADF framework if the scope itself is modified, such as by calling the scope's put(), remove(), or clear() methods.

If an application is not deployed to a clustered environment, the tracking of changes to ADF memory scopes is not needed, and by default, this functionality is disabled. To enable the ADF Controller to track changes to ADF memory scopes and replicate the pageFlowScope and viewScope within the server cluster, set the <adf-scope-ha-support> parameter in the adf-config.xml file to true. Because scope replication has a small performance overhead, it should be enabled only for applications running in a server-cluster environment.

Example 17-8 shows adf-scope-ha-support set to true in the adf-config.xml file.

Example 17-8 adf-scope-ha-support Parameter in the adf-config.xml File

<adf-scope-ha-support>true</adf-scope-ha-support>