Skip Headers
Oracle® Fusion Middleware Fusion Developer's Guide for Oracle Application Development Framework
11g Release 1 (11.1.1)
B31974-03
  Go To Table Of Contents
Contents
Go To Index
Index

Previous
Previous
 
Next
Next
 

18 Creating Complex Task Flows

This chapter describes how to use advanced features of ADF task flows. For basic information about using task flow activities, see Chapter 15, "Working with Task Flow Activities".

This chapter includes the following sections:

18.1 Introduction to Complex ADF Task Flows

After creating a basic unbounded or bounded task flow and adding task flow activities to it, you can perform specialized tasks such as transaction management and reentry.

If you want to work with ADF regions, see Chapter 17, "Using ADF Task Flows as Regions".

To work with parameters, see Chapter 16, "Using Parameters in Task Flows".

18.2 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 or not 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 performing cleanup before exiting the task flow.

18.3 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 Demo 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 backorder 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 18-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 18-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. 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 ADF controller.

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


18.3.1 How to Enable Transactions in an ADF Bounded Task Flow

Before you begin:

  • Create 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 editor for the called ADF bounded task flow, click Behavior and expand the Transaction section.

  3. Choose one of the following from the transaction dropdown 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 in any transaction management.


    Note:

    After choosing a transaction option, you may also need to select the data-control-scope option for the bounded task flow to determine whether there are any interactions between the options. For more information, see Section 16.4.1, "What You May Need to Know About Managing Transactions".

  4. If you choose requires-existing-transaction or requires-transaction, you can optionally select true in the no-save-point dropdown 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: Select to commit the existing transaction to the database.

    • rollback:Delect to roll 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 the task flow is exited. The save point that was created upon task flow entry will be restored.

18.3.2 What Happens When You Specify Transaction Options

Example 18-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 18-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 18-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 For more information about defining control flow upon return (see Section 15.7, "Using Task Flow Return Activities".

18.3.3 What You May Need to Know About Data Control Scoping with Task Flows

The ADF Model layer uses the interface DataControlFrame to manage a transaction in which the data controls within the frame participate. The DataControlFrame interface has methods such as beginTransaction(), commit(), and rollback(). Similarly, ADF Controller allows a task flow to be used to demarcate a transaction boundary, beginning a transaction at task flow entry and either committing or rolling back the transaction on task flow exit.

ADF Controller supports the following options upon entry:

  • Begin a new transaction.

  • Require an existing transaction and participate in it.

  • Require a transaction, which will begin a new transaction if the caller does not have one open.

  • No transaction support (Default).

The behavior of these task flow transactional settings depends the data control scope. Table 18-1 shows how these transaction settings behave based on the data control scope of the task flow.

Table 18-1 Transaction Settings Behavior

Setting Shared Data Control Scope Isolated Data Control Scope

Requires Transaction

Begins a new transaction if one is not already open.

Always begins a new transaction.

Requires New Transaction

Begins a new transaction if one is not already open and throws an exception if one is already open.

Always begins a new transaction.

Requires Existing Transaction

Throws an exception if the transaction is not already open

Invalid. This option cannot be selected.

None

The DataControlFrame is shared without without an open transaction.

A new DataControlFrame is created without an open transaction.


18.4 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 15.3, "Using URL View Activities" for more information on how to configure view activities.

18.4.1 How to Set Reentry Behavior

You can set reentry behavior on a bounded task flow.

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

18.4.2 How to Set Outcome-Dependent Options

You can set outcome-dependent options only on ADF bounded task flows that have specified the reentry-outcome-dependent option.

Before you begin:

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

  • In the ADF bounded task flow, add a task flow return activity. For more information, see Section 15.7, "Using Task Flow Return Activities".

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

To set outcome-dependent options:

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

  2. In the Property Inspector, click Behavior.

  3. In the Reentry dropdown list, select either:

    • reentry-allowed

    • reentry-not-allowed

18.4.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, the value of a managed bean on the reentered task flow is set back to its the original value, the same value that it had was before the end user left the parent task flow. This is done 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 18.4.1, "How to Set Reentry Behavior" and Section 18.4.2, "How to Set Outcome-Dependent Options")

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.

18.5 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. For more information, see Section 14.1.3, "Control Flows".

You can optionally specify an exception handler for both ADF bounded and unbounded task flows. 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 if 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.

18.5.1 How to Designate an Activity as an Exception Handler

You can designate an 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, and choose Mark Activity > Exception Handler.

    A red exclamation point is superimposed on the activity in the task flow to indicate that 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, and 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.

18.5.2 How to Handle Exceptions During Transactions

Any ADF bounded task flow representing a managed transaction should designate an exception handling activity. When running an ADF bounded task flow managed transaction, ADF controller attempts to commit the transaction when it reaches a task flow return activity identified in metadata for a commit. For more information, see Section 18.3, "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.

18.5.3 What Happens When You Designate an Exception Handler

After you designate an activity to be 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 18-2.

Example 18-2 <exception-handler> element

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

18.5.4 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, your should application should 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 phase 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 to see whether dependent fields are in sync. In these cases, the error message is usually attached to the whole page, which this logic can access.

You should attach errors detected during the Validate Model Updates phase to the JSF page, and call FacesContext.renderResponse(). 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".

18.6 Saving for Later

Saving for later captures a snapshot of an ADF 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. The Customer Registration page of the Fusion Order Demo shown in Figure 18-2 contains a method that sets a save point when each page of the Customer Registration train is saved. The method is set to #{backingBeanScope.registrationBean.createSavePoint}.

Figure 18-2 Create Save Point

Create Save Point

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 18.6.2, "How to Restore Save Points".

As shown in Figure 18-3, you can use the save point restore activity to restore whatever was captured at the original save point, for example, values that the user entered on each saved page of the train.

Figure 18-3 Save Point Restore Activity

Save Point Restore Activity

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.

For more information, see Section 15.8, "Using Save Point Restore Activities".

18.6.1 How to Add Save For Later Capabilities

Figure 18-4 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 18-3). The createSavePoint method adds a save-point-id. The save-point-id captures everything up to the point in the task flow 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 restore the application state and data that was captured when the save point was originally created.

Figure 18-4 Save For Later Task Flow

Task flow with save for later capability.

In the editor, 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 18-3. If you do this, you can update the save-point-id with any custom attributes you create on your method.

Example 18-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);
          }    }
 

You can add a call to a custom method to a task flow, similar to Figure 18-4. The method creates a save point ID similar that of to Example 18-3.


Note:

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.

To add save for later capability to a task flow:

  1. Drag a method call activity from the ADF Task Flow dropdown 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 14.2.4, "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. For more information, see Section 18.14.1, "How to Specify Save for Later Settings".

18.6.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 points should be restored, the save point restore activity uses the save point that was originally created with the createSavePoint method.

You can obtain a list of the current persisted save points with createSavePoint. However, ADF Controller does determine which save points to restore. A user must select the save point from a list or the application developer must 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. From the ADF Task Flow page of the Component Palette, drag a save point restore activityand 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}.

18.6.3 What You May Need to Know about Implicit and Explicit Save For Later

There are two categories of saving for later:

  • Explicit

    For example, a page contains a button that the user can click to save all data entered so far on the page. See Section 18.6.2, "How to Restore Save Points" for more information.

    Explicit save for later is available for both ADF unbounded and bounded task flows.

  • Implicit

    For example, a user accidentally closes a browser window without saving data entered on a page, a user logs out without saving the data, or the session times out. See Section 18.6.4, "How to Enable Implicit Save for Later" for more information.

    For an implicit save, this snapshot 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.

    An implicit save for later can only originate from a bounded task flow. To enable implicit savepoints, the enable-implicit-savepoints property must be set to true in the adf-config.xml configuration file. The example below shows how to set up adf-config.xml to enable implicit save point capability within an application. For more information, see Section 18.14, "Using the adf-config.xml File to Configure ADF Controller".

    <adf-config xmlns="http://xmlns.oracle.com/adf/config">
        <adfc-controller-config xmlns=     "http://xmlns.oracle.com/adf/controller/config">
           <enable-implicit-savepoints>true       </enable-implicit-savepoints>
         </adfc-controller-config>
    </adf-config>
    

    Implicit save points are generated only if a critical task flow is present in any of the page flow stacks for any view port under the current root view port. An implicit save point is not generated if the request is a request for an ADF Controller resource, such as:

    • Task flow call activity

    • Task flow return activity

    • Save point restore activity

    • A dialog

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.

18.6.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

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


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. For more information, see Section 18.14, "Using the adf-config.xml File to Configure ADF Controller". 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 on 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.

18.6.5 What You May Need to Know About Application State

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

Table 18-2 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 state 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 page flow scope. The managed beans must be serializable in order to be saved. If you have page flow scope 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 its lifespan 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.

ADF Model State

Fusion web applications use ADF Model to represent the persisted data model and business logic service providers. The ADF Model holds any data model updates made from when the current bounded task flow begins. The model layer determines any limits on the saved state lifetime. For more information, see Chapter 39, "Application State Management".


18.6.6 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 the application state.

Each task flow definition can specify 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 that the application's state is correct before proceeding with the restore. For example, the application developer must provide restoration logic for temporal validations.

18.6.7 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 18.14.1, "How to Specify 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 18-4.

Example 18-4 SetSavePointTimeToLive Method Syntax

void setSavePointTimeToLive(long timeInSeconds) 

When 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 18-3).

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

To use the Save for Later feature with a Business Components 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 Application Module and choose Configurations.

  2. Click Edit.

  3. Click the Properties tab.

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

18.6.9 What You May Need to Know About Specifying the Correct JNDI Connection Name

A JNDI connection name for a save point application is specified in adf-config.xml. If the JDeveloper connection name is Connection1, the JNDI connection name would be jdbc/Connection1DS. On Weblogic Server, the JNDI format is different, for example: java:comp/env/jdbc/Connection1DS.

Example 18-5 JNDI Connection Name

<adf-controller-config xmlns="" TARGET=_blank>
http://xmlns.oracle.com/adf/controller/config">
   <savepoint-datasource>jdbc/Connection1DS</savepoint-datasource>
   <enable-implicit-savepoints>true</enable-implicit-savepoints>
</adf-controller-config>

should be migrated to the following:

Example 18-6 JNDI Connection Name on WebLogic Server

<adf-controller-config xmlns="" TARGET=_blank>
http://xmlns.oracle.com/adf/controller/config">
   <savepoint-datasource>java:comp/env/jdbc/Connection1DS</savepoint-datasource>
   <enable-implicit-savepoints>true</enable-implicit-savepoints> 
</adf-controller-config>

18.7 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 18-5 shows a train in the Fusion Order demo application that is called when an end user clicks the Self-register link on the User Registration page.

Figure 18-5 Self-Registration Train in Fusion Order Demo 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 similar to that shown in Figure 18-6. It that enables the user to navigate through the train stops in an order specified in the underlying train model.

Figure 18-6 Train UI Component

Train UI Component

The optional Train Button Bar component shown in Figure 18-7 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 18-7 Train Button Bar UI Component

trainButtonBar UI component.

18.7.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, and 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 18-8 displays the bounded task flow that the Fusion Order Demo application uses to create the self-registration train shown in Figure 18-5.

Figure 18-8 customer-registration-task-flow

customer-registration-task-flow

Figure 18-9 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. For more information, see Section 18.7.2, "Train Sequences". Although you can't drag the dotted line to change the sequence, you can right-click 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 18-9 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. For more information, see Section 18.7.4, "What You May Need to Know About Grouping Activities".

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. For more information, see Section 18.7.7, "What You May Need to Know About Branching".

18.7.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.

A single train can contain both sequential and nonsequential stops. In Figure 18-10, the first step is the current train stop. Second stop is sequential because the user can click it only after visiting first stop. Third step is nonsequential because it can be clicked immediately after the user visits first stop without also having to visit second stop.

When first step is the current stop, the end user cannot click the fifth and sixth steps , indicating that they are sequential.

Figure 18-10 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 better 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 14.4, "Designating a Default Activity in an ADF Bounded Task Flow".

18.7.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. For more information, see Section 14.2, "Creating Task Flows".

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

  • Right-click 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, you can double- click it later to create a new JSF page.


    Tip:

    Don't worry about 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 the stop corresponding to an activity in the diagram. Choose Train, and then choose a menu item to move the train stop within the sequence, for example, Move Forward or Move Backward.

  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.

18.7.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. As shown in Figure 18-8, in the customer registration bounded task flow, 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 approach for grouping a set of activities to form a train stop is to use a child ADF bounded task flow (see Section 18.7.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 nonview activity through the next view activity will be considered part of the train stop's execution.


Although this approach groups 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 18-11. All activities leading from the first nonview 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, 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 train stop, all activities will be performed beginning with the activity the wildcard control flow points to.

In Figure 18-11, the SurveyPage2 train stop consists of the following group of activities that execute in the following order:

Figure 18-11 Grouping Activities Without Using a Task Flow Call Activity

Grouping activities without a task flow call
  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.

18.7.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. For more information, see (Section 15.6, "Using Task Flow Call Activities". 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 activities are grouped in a called child bounded task flow, nonview 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 18-12 shows the SurveyTaskFlow train stop, a task flow call activity that calls a child bounded task flow.

Figure 18-12 Task Flow Call Activity Train Stop

Task flow call activty train stop

The child bounded task flow is shown in Figure 18-21

Figure 18-13 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 of whether 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 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 18-12 and Figure 18-13, the value specified in the from-outcome for the control flow case (done) matches the task flow return activity outcome value.

18.7.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 (that is, it 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.

18.7.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 18-14.

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 18-14.

Figure 18-14 Branching within Grouped Activities for a Single Train Stop

Branfching within grouped activites

18.8 Running Multiple ADF Task Flows

Multiple ADF task flows may run simultaneously within an ADF application and within the same HTTP session. In many cases, you can run each ADF task flow in a separate browser window. For example a customer support representative might work multiple customer cases simultaneously, each within its own browser window.

ADF task flows can be initiated to display within new browser windows from either a request by the application or the browser.

An application may also use different frames, multiple portlets, or ADF regions within a single browser window A view port describes the area that displays a view and its independent navigation. A view port can be in a full browser window, a frame, a portlet, or an ADF region.

Each view port maintains a task flow stack that represents an end user's current navigational state. A view port's task flow stack begins with the application's top-level ADF task flow as the first entry on the stack. As the end user navigates into an ADF bounded task flow, additional entries are pushed onto the stack representing the ADF bounded task flow. As the end user navigates out of ADF bounded task flows, entries are removed from the stack. If the end user navigates away from the parent page, any child modes and modal dialogs are closed.


Best Practice:

Although it is not necessary to notify the ADF Controller when a browser window is closed, it is at good design practice for the framework. This gives ADF Controller an opportunity to clean up resources allocated to the browser window's view port, such as managed beans and open, unresolved transactions.

18.8.1 Understanding How the ViewPortInstance Works in ADF Regions

View ports can also be created when a page with an ADF bounded task flow region is rendered. When a request for the first activity in an ADF application is received, ADF Controller creates a view port and a ViewPortContext corresponding to the main browser window. Each ADF region has an associated ViewPortContext instance. The ViewPortContext instance is created during the Restore View phase of the JSF lifecycle.

ADF controller uses the ViewPortContext instance every time it needs to interact with JSF RI FacesContext. The ViewPortContext is responsible for dispatching all calls to FacesContext directly or to ADF view APIs. For example, when the ADF controller finds a new view activity for the view port, it calls ViewPortContext.setRootViewId. For the ADF bounded task flow representing the root page, this call results in calling FacesContext.setRootViewId. For ADF bounded task flows embedded inside an ADF region, the ViewPortContext keeps track of the root view ID. When ADF View is ready to assemble the page markup for the root page, it can access the ADF region component's view ID stored on ViewPortContext.

For example, once a page containing ADF regions is rendered, an end user might click a button inside an ADF region causing a form submit:

  1. ADF controller handles the request in the context of a view port created for the ADF region.

  2. The correct ViewPortContext is set up by the ADF region before the ADF controller NavigationHandler is called.

  3. Based on from-action and from-outcome values, ADF Controller produces the ID of the next view activity for the ADF bounded task flow region and sets it on the ViewPortContext.

  4. ADF view will use the view activity ID in the Render Response stage of the JSF lifecyccle to pick up new markup for the ADF region. Because the NavigationHandler is called in the Region context, the root view ID for the main page is not be reset.

  5. When the end user navigates away from the page, the ADF bounded task flow region is destroyed. The view layer again notifies ADF controller in order for resources allocated to the ADF region to be released.

18.9 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, as shown in Figure 18-15.

Figure 18-15 Source Task Flow

A source task flow.

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.


Suppose you created a task flow containing a view and task flow call activity similar to that shown in Figure 18-15. When a user enter a value and returns in the launch_page view activity shown in Figure 18-16, the bounded task flow associated with calltoTarget executes.

Figure 18-16 launch_page

launch_page

On the 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 a modal dialog can also pass values back to the caller.


Note:

If your application uses ADF Controller features (for example, ADF task flows), you cannot specify dialog: syntax in navigation rules within faces-config.xml.

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>

18.9.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 18-15. 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 18-16

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 18-15, this is calltoTarget.

  5. In the UseWindow dropdown 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 dropdown list, select true.

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

18.9.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 For more information, see "Using Input Components and Defining Forms" in the Oracle Fusion Middleware Web User Interface Developer's Guide for Oracle Application Development Framework. 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. See Section 16.3, "How to Pass Parameters to an ADF Bounded Task Flow"for more information.

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

  • A return value definition on the called bounded task flow. This indicates 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 indicate where the calling task flow can find return values. See Section 16.5, "Specifying Return Values" for more information.

Before you begin:

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 dropdown 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 specified a return value definition on the called task flow, see Section 16.5, "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 sample EL expression, backingBean is the name of a backing bean and gotoModalDialog is the id of the launching command button shown in Figure 18-16.

    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.

18.9.3 What You Should Know About Ctrl + N Support

If a user presses Ctrl+N in an ADF application, the home page of the application displays. To enable this behavior to occur, you must identify the home page in the web.xml configuration file. The home page must be identified by a view activity ID. Example 18-7 contains an example configuration.

Example 18-7 web.xml configuration

<welcome-file-list>
    <welcome-file>viewActivityId</welcome-file> 
</welcome-file-list>

18.10 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 be 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 18.5, "Handling Exceptions" for more information.

You can base a new 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 14.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.

18.10.1 How to Copy and Reference an ADF Task Flow Template

There are two methods for reusing an 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 18-17. 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 and any control flows between them, and it 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 shown in Figure 18-17, 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 deselect the Train checkbox on the Behavior page of the overview editor for task flow definitions. The difference in how the Train checkbox is set for the parent template and the child task flow is a collision.

Table 18-3 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 18-3 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 is 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.

18.10.2 How to Create 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 the process for creating an ADF bounded task flow based on a template For more information, see Section 14.2, "Creating Task Flows".

18.10.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 18-17, 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 18-17 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. For more information, see Section 14.5, "Running ADF Task Flows".

18.10.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. For more information, see Section 18.10.2, "How to Create an ADF Task Flow Template from Another Task Flow".

To create an ADF task flow template from scratch:

  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, expand Web Tier.

  3. Select JSF, and then ADF Task Flow Template and click OK.

    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.

  4. 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.

  5. Click OK.

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

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

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

  7. 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.

18.10.5 What Happens When You Create an ADF Task Flow Template

As shown in Example 18-8, 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 18-8 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>

18.10.6 What You May 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.Doing 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 19.2.1, "How to Use ADF Data Binding in ADF Page Templates".

18.11 Creating a Page Hierarchy

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 18-18 shows a sample page hierarchy.

Figure 18-18 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 Fusion application suite home page displays the Human Resources page hierarchy shown in Figure 18-18. Clicking the link on the Benefits tab displays the page hierarchy shown in Figure 18-19.

Figure 18-19 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 the XML menu model to build the page hierarchy. If you use this method, the following is generated automatically for you:


Note:

This section describes creating a page hierarchy. 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.


18.11.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 per hierarchy.

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

  • itemNode: Contains a node that performs navigation upon user selection. For example, clicking the Medical, Dental, or Vision links on the Benefits page navigates to the Medical, Vision, or Vision pages.

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

    The Benefits page in Figure 18-9 , 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 results in the Medical page being displayed

  • 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. For example, the Benefits hierarchy is linked to the Human Resources hierarchy using a shared node.

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 three links item nodes and Benefits a group node.

18.11.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 of the hierarchy in the Structure window.

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

  • 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 18-20 Menu Hierarchy

Menu hierarchy.

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.

To build a hierarchy, you could create a group node called Benefits and three items nodes called Medical, Dental, and Vision.

Before you begin:

Create the pages you will use in your menu hierarchy. For more information, see Section 19.3, "Creating a Web Page".


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.

To create a submenu containing group and item nodes:

  1. For each menu that will be in the final page hierarchy, create an XML source file by deselecting the Create as Bounded Task Flow checkbox in the Create ADF Task Flow dialog. See Section 14.2.1, "How to Create an ADF Task Flow" for more information.

    For example, Figure 18-20 contains an adfc-benefits-config.xml source file that corresponds to the Benefits sub 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.

  2. In the Application Navigator, double-click the source file to open it in the editor.

  3. 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 Human Resources menu will have a tab 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.

  4. 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.

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

    For example, you could begin by right-clicking 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.

  6. 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.

  7. Click OK.

    As shown in Figure 18-21, 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 18-21 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.

  8. 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. By default, they are all siblings and none is a parent of any other node.

  9. 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 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 of the Property Inspector, 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.

To attach a menu hierarchy to another hierarchy using a shared node:

  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.

  4. 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.

  5. To run the finished page hierarchy:

    1. In the Application Navigator, right-click 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 14.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 18.12, "Specifying Bootstrap Configuration Files".

18.12 Specifying 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 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.

ADF Controller uses MDS as a metadata storage layer. ADF calls MDS to load /WEB-INF/adfc-config.xml and /META-INF/adfc-config.xml resources. By default, ADF Controller looks for an adfc-config.xml file in these directories for all jar files on the classpath.

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, and then click Metadata Resources.


Note:

You should specify metadata resources within the adfc-config.xml file or any of the bootstrap configuration files referenced within adfc-config.xml.

18.13 Using BPEL with ADF Task Flows

Business Process Execution Language (BPEL) is a language for composing multiple services into an end-to-end business process. For more information about BPEL, see the Oracle Fusion Middleware Developer's Guide for Oracle SOA Suite. You can use BPEL with ADF task flows to:

18.13.1 How to Invoke a BPEL Process from an ADF Task Flow

You can use any of the following techniques for calling a BPEL process from an ADF unbounded or bounded task flow:

  • Bind an existing method call activity on the task flow diagram to a managed bean method wrapping the BPEL process call as a Java component. For more information, see Section 15.5, "Using Method Call Activities".

  • Bind an existing method call activity on the task flow diagram to an action binding performing the BPEL process call as a web service For more information, see Section 15.5, "Using Method Call Activities"for more information. The web service data control is the preferred approach to use when calling as a Web Service.

During runtime, the application will place the request to the BPEL process in the form of a payload. The BPEL process receives the payload and responds with a payload containing the information the application requested. The BPEL process outcome is to continue control flow in the ADF unbounded or bounded task flow.

18.13.2 How to Call an ADF Bounded Task Flow from BPEL

BPEL workflow services allow human interactions to be interspersed between tasks within end-to-end flows. During a BPEL process flow, a task is assigned to a user or role and then it waits for a response. The user will act on the task using the BPEL worklist application. The worklist application is able to initiate an ADF bounded task flow assigned as part of the user's task. ADF bounded task flow functionality can be used while still taking advantage of the human interaction framework of a BPEL process (for example, notifications, escalation policy, and worklist).

18.14 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.

18.14.1 How to Specify 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 18-4.

Table 18-4 Save For Later Configuration Properties

Property Description

savepoint-datasource

JNDI name of the data source, for example, jdbc/DBConnectionIDS

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. For more information about creating a save point, see Section 18.6.1, "How to Add Save For Later Capabilities".

The default setting for this property is false.


18.14.2 How to Validate 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 activityID 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.

18.14.3 How to Search 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 that 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.

18.14.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 that 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 session scope, page flow scope, and view scope need to be serializable.


    Tip:

    To identify failures with objects stored in page flow scope and viewscope, use writeObject(). This method provides additional information in an exception about the object and scope that failed to serialize. Additional information might be a region's page flow scope and the key of the object.

  • Make sure that the ADF framework is aware of changes to managed beans stored in ADF scopes (view scope and page flow scope).

When a value within a managed bean in either view scope or page flow scope is modified, the application needs to notify the ADF framework so that it can ensure the bean's new value is replicated.

In Example 18-9, an attribute of an object in view scope is modified.

Example 18-9 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, as shown in Example 18-10. The markScopeDirty() method accepts only viewScope and pageFlowScope as parameters.

Example 18-10 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. If the scope itself is modified by the scope's put(), remove(), or clear() methods, it is not necessary to notify the ADF framework.

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 ADF Controller to track changes to ADF memory scopes and replicate the page flow scope and view scope 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 18-11 shows adf-scope-ha-support set to true in the adf-config.xml file.

Example 18-11 adf-scope-ha-support Parameter in the adf-config.xml File

<?xml version="1.0" encoding="US-ASCII" ?>
<adf-config xmlns="http://xmlns.oracle.com/adf/config"
      xmlns:adfc="http://xmlns.oracle.com/adf/controller/config">
   <adfc:adf-controller-config>
...
    <adfc:adf-scope-ha-support>true</adfc:adf-scope-ha-support>
...
  </adfc:adf-controller-config>
...
</adf-config>