Classifying ADF Task Flow Navigation Choices

Having written the Angels in the Architecture: An ADF Application Architectural Blueprint presentation in 2011 it spawned a number of side projects which I had scribbled down but taken no further. Starting at Oracle has given me a little more time to rummage through my notebooks and turn these ideas into blogs posts hopefully to help others.

In the Angels in the Architecture presentation there was an in depth look at how Bounded Task Flows (BTF) in JDeveloper 11g+ could be placed in their own workspace and published as ADF Libraries for reuse in a master composite ADF application. In consuming the BTFs in the master application, it isn't uncommon to make use of the consumed BTFs in a parent composite BTF that brings the moving parts together. This is truly one of the delights of BTFs, the ability to shuffle the bits around like Lego to build any application you want.

It was in this composition that I discovered another interesting area of BTFs yet to be documented, that of the different navigation models used beyond just the concepts of Unbounded Bounded Task (UTFs) vs Bounded Task Flows (BTFs). This blog posts takes a stab at describing the different models. It shouldn't be considered complete, just a starting point to help you understand the options, and a chance for me to change my scribbled notes into something more substantial.

Unbounded Task Flows vs Bounded Task Flows

Of course for ADF beginners it's worth going over the basics and describing the characteristics of Unbounded Task Flows (UTFs) and Bounded Task Flows (BTFs).

Unbounded Task Flows of which every application has at least one comprise the main page flow of your application. Whether you're building an application with many separate pages each with their own URL, or a single page desktop like application with portals/regions, you'll have a UTF.

In terms of navigation an example UTF looks as follows:

The navigation characteristics of a UTF many of which been documented before include:

  • There is no set start or end to the UTF (thus the name "unbounded"), the user can enter the application at any activity.
  • Navigation is a combination of user free-form and design time structured (explained further next)
  • Free-form allows the user to access any view activity via a URL.
  • Because of the free-form navigation model, the minimum amount of steps to get to any view activity is 1.
  • Isolated activities are still accessible thanks to their URLs.
  • Structured allows developers to optionally define uni or bi directional navigation between nodes.
  • Wildcards provide a uni-directional leap from a source activity to a defined destination activity.
  • The UTF has no defined exit points for the user. In fact every activity is an exit point, the user can leave the application at any point.

Bounded Task Flows navigation takes a more constrained approach to navigation:

The characteristics of navigation within BTFs include:

  • As the name suggests, they're bounded, with one entry point and one or more exit points for the user.
  • There is no free-form navigation, all navigation (both uni and bi-directional) must be through predefined navigation rules or wildcards.
  • You cannot access any activity inside the BTF by an addressable URL.
  • Because of the structured navigation model, the minimum number of steps to get to any activity within the BTF is dictated by the developer (unlike the free-form nature of UTFs).
  • Isolated nodes are inaccessible.

Inter-Task Flow navigation - task flow calls and regions

Before we investigate task flow navigations further, readers need to be familiar that the two mechanisms for tasks flows to call each other:

1) To call a task flow based on pages we must use a task flow call

2) To call a task flow based on page fragments, we must embed the page fragment task flow as a region in a page or another page fragment.

Note how I use the term task flow here rather than Unbounded or Bounded Task Flows. The mechanisms for the different types of task flows to call each other is the same across both.

In addressing point 2 above it is an interesting one as the idea of embedding brings us to the idea of the "stack".

Stack navigation

At its simplest "stack navigation" is when one task flows call another without terminating the first:

To be precise stack navigation occurs when:

  • A source task flow calls a destination task flow
  • Control is passed to the destination task flow until it terminates
  • Upon which control is passed back to the source/caller
  • During the stack the state of the source task flow is persisted
  • The state of the destination task flow only exists for its life

The easy analogy here for developers to understand is the 3GL equivalent of functions calling functions.

Of course the "stack" model can be extended and we can have a set of task flows calling each other in a deep stack:

Some points on the stack:

  • It's suitable for both page or page fragment task flows
  • Task flow calls and returns are what allow the stack to grow and shrink.
  • As we progress deeper into the stack, as the previous task flows are still live and their state stored in memory, we will consume more memory
  • On returning to a previous item in the stack, its state is restored in tact with out modifications needed.
  • It is well suited to logical drill up/down solutions.
  • There are no short cuts from the stack.
  • It's messy at design time to reorganize the stack if we get the stack order wrong.
  • Task flow parent actions or contextual events to manipulate the calling task flow are not possible.
  • Task flow calls allow a terminating task flow to pass parameters back to the caller.

Network navigation

"Network navigation" is where we chain a number of task flows together in one composite master.

Relevant points of the network navigation model:

  • It is suitable for both page or page fragment task flows
  • Navigation between flows is controlled by a master composite task flow.
  • It's very easy to reorganize the calling order in the composite task flow.
  • At most there's only the two task flows on the stack, the composite or the called task flow, thus reducing concerns on the memory consumed.
  • If we do return to a previously visited called task flow in the composite, to provide a seamless experience for the user where it appears we never left the task flow, we need to reestablish it's similar state to when we left it. This will optionally require more task flow parameters and more logic internally to reexecute previous processing.
  • Task flow parent actions or contextual events to manipulate the calling task flow are not possible.
  • Task flow calls still allow a terminating task flow to pass parameters back to the caller.
  • Better suited to logic path or wizard style interfaces (noting the similarity to trains).

At this point we can start to see one of the key differentiators technically with stack vs network navigation is the stack model takes more memory (depending on it's depth), while network takes less but may require more processing. Readers should be careful not to make an ill formed decision here as I've not given you any empirical evidence on which one is better or worse from an overhead point of view. As example if stack navigation only takes up 1k per user, who cares. But if it takes up megabytes, there's something to worry about. The actual numbers will be dependent on your custom solution and you need to take your own measurements to make this judgement.

Hybrid navigation

Of course it's possible to have a combination of both stack and network navigation:

I wont go into details of the pro's and con's here as they are just a combination of the stack and network navigation characteristics.

Nested region navigation

"Nested regions navigation" is my name for when a page or page fragment embeds one or more separate regions to one or more separate Bounded Task Flows based on fragments. Unfortunately there's not an easy JDeveloper screenshot to describe this so we'll use a diagram instead:

The characteristics of this model:

  • The call from a region to a BTF can be thought of as a 2 level stack but where the state of the caller and the nested region BTF run in parallel.
  • Navigation within each BTF is independent of the parent task flow and as such can be any combination of the navigation models: stack, navigation or hybrid.
  • The nested BTF can communicate to the parent and other nested BTFs through parent actions or contextual events.
  • On termination of a nested BTF there is no way for the BTF to return parameters.
  • This includes the notion of inline popups containing regions within the parent page or fragment.
  • The more regions you have, the more memory and processing required for the page.

Parallel navigation

Finally returning to the model where one task flow calls another through a task flow call, task flow calls allows BTFs based on pages to be called either as an inline popup or external window.

The inline popup navigation is a kin to the "Nested region navigation" previously described.

The external window navigation is more complicated as this navigation occurs separately in a new browser window separate to the current browser window, thus the title "parallel navigation". While it doesn't have a separate HTTP session, it does have it's own pageFlowScope and it's operation is separate to that of the main window.


What can be seen from the different navigation models is they support different user experiences, different technical challenges and different features that can be utilised in each. It's simply not an understanding of task flows and their features ADF architects need. Rather an understanding of the different navigation models will help architects design new ADF applications.

If any readers come up with different navigation models I'd be glad to hear about them.


Very good article.

A related aspect is about how to trigger the navigation and how to pass data together with the navigation(payload).

For instance we use contextual events to trigger an action in a parent composite taskflow from children taskflows embedded in its fragments.

Here is a sample usecase:

- main_taskflow having following structure:

(filter_orders_view)(default activity)

- filter_orders_view has 2 regions in a panel tabbed holding 2 taskflows(one for each orders filter criteria, lets say one by departments selling and one by products sold);

- each filter criteria type taskflow produces a contextual event with the filter data as payload;

- filter_orders_view subscribes to the events and in the handler stores the filter from the payload in pageflowScope and triggers programatically a navigation(ex: main_taskflow.show_orders);

- navigation ends up in main_tasfklow.orders_list_taskflow which uses the filter stored previously as input parameter;

Posted by Adrian Andreca on February 23, 2012 at 07:33 PM WST #

Post a Comment:
Comments are closed for this entry.

Not a selfie
Chris Muir
Oracle Mobility and Development Tools Product Manager

The views expressed on this blog are my own and do not necessarily reflect the views of Oracle.



« August 2016