Você está na página 1de 19

Functional

Pattern ADF Region Interaction


Pattern 1.0
Revision
Technologies JDeveloper 11g, ADF, ADF Faces, ADF Controller
Keywords Region
Publisher David Giammona
Publish date January 22, 2009

Problem Description
There are often times when application interaction is required between an ADF region
and its containing page. This communication typically involves initiating navigation or
sharing application data. Since an ADF region represents a separate task flow definition
with its own boundaries, any interaction across those boundaries must be considered
carefully. Depending on the specific ADF region interaction use case, different
approaches are utilized to implement the desired behavior. The many different
approaches involved under the umbrella of ADF region interaction can make selecting
the appropriate solution a challenge. This document describes each of these ADF region
interaction approaches to assist in determining which best fits any given situation.
If the initiation of navigation is required, the table below identifies the recommended
approach based on the corresponding region use case. Each approach is described further
within the document.
Navigation Recommended Approach
Navigate Root View Port (Browser) Task Flow URL View Activity
Navigate Containing Page From Region Task Flow Parent Action Activity
Navigate Region From Containing Page queueActionEventInRegion(…) Method
Identify Navigation Within Region regionNavigationListener

If data sharing is required, the table below identifies the recommended approach based on
the corresponding region use case. Each approach is described further within the
document.
Data Shared Recommended Approach
Entire Data Control Frame Task Flow Definition <data-control-scope>
Small Subset When Restarting Region Task Flow Definition Input Parameters
Task Flow
Small Subset Without Restarting Region Contextual Framework Events
Task Flow - or -
Task Flow Definition Input Parameters for Objects Passed By
Reference
Available Outcomes Based on Current Region Capabilities
State of Region

ADF Region Interaction 1


Functional

Implementing the Pattern


Navigation – Task Flow URL View Activity
If a region needs to initiate navigation of the root browser page, a task flow URL view
activity can be used. A task flow URL view activity redirects the root browser page
(view port) to a specified URL. No matter where the URL view activity is performed,
even from within a nested region, it will always navigate the root browser page.
Task flow URL view activities incorporate the following metadata within a task flow
source file:
<url-view id="urlView1">
<url>http://www.google.com</url>
</url-view>

For further details on task flow URL view activities, refer to the Oracle Fusion
Middleware Fusion Developer's Guide for Oracle ADF within Section 14.3, "Using URL
View Activities".

Navigation – Task Flow Parent Action Activity


If a region needs to initiate navigation of the parent page, a task flow parent action
activity can be used. Parent action activities aren’t limited to only initiating navigation
for the root browser page like task flow URL view activities. They also have an
advantage in that if the outcome specified for navigation of the parent task flow is not
found at runtime, optionally a different outcome can be specified for an alternate
navigation back within the same region.

ADF Region Interaction 2


Functional

Task flow parent action activities incorporate the following metadata within a task flow
source file:
<parent-action id="Exit">
<parent-outcome>globalHome</parent-outcome>
</parent-action>

In the customer-registration-task-flow shown above, the activity labeled “Exit” is a parent


action activity. The customer-registration-task-flow is utilized as a region on the register
page within the adfc-config shown below. If the “exitRegistration” outcome is perfomed
within the customer-registration-task-flow region, the parent action activity will be
executed. It will initiate navigation within the adfc-config parent task flow using the
outcome “globalHome” as specified within its metadata. The “home” page within the
adfc-config will then be displayed.

ADF Region Interaction 3


Functional

For further details on task flow parent action activities, refer to the Oracle Fusion
Middleware Fusion Developer's Guide for Oracle ADF within Section 14.9, "Using
Parent Action Activities". Additional information can also be found in section 16.1.6
“How to Trigger Navigation of an ADF Region's Parent Task Flow”. Example used
taken from the Oracle Fusion Store Front Demo Application.

Navigation – queueActionEventInRegion(…) Method


When a page needs to initiate navigation within one of its contained regions, the
recommended approach is to utilize the queueActionEventInRegion(…) method located
within the oracle.adf.view.rich.component.rich.fragment.RichRegion class. The
queueActionEventInRegion(…) method queues an ActionEvent to behave as if it was
queued on a UIXCommand component existing inside the region or nested region.
For example, the buttons on the page shown below navigate the contained region between
the Employees and Departments page fragments.

ADF Region Interaction 4


Functional

The contained region’s task flow definition includes the “Employees” and “Departments”
view activities along with the control flow between them. The
queueActionEventInRegion(…) method initiates the “employees” or “departments”
outcome depending on which button is selected. Based on the region’s current state, the
buttons are disabled accordingly using region capabilities.

The Java methods performed by the “Employees” and “Departments” buttons on the
parent page might be similar to the following:

private String region = "taskf1";


private String outcome = "departments";

public void handleOuterPageActionDepartments(ActionEvent actionEvent) {


region = "taskf1";
outcome = "departments";
handleOuterPageAction(actionEvent);

ADF Region Interaction 5


Functional

public void handleOuterPageActionEmployees(ActionEvent actionEvent) {


region = "taskf1";
outcome = "employees";
handleOuterPageAction(actionEvent);
}
public void handleOuterPageAction(ActionEvent actionEvent) {
UIComponent regionComponent =
actionEvent.getComponent().findComponent(region);
if (regionComponent instanceof RichRegion) {
FacesContext fc = FacesContext.getCurrentInstance();
ExpressionFactory ef =
fc.getApplication().getExpressionFactory();
ELContext elc = fc.getELContext();
MethodExpression me = ef.createMethodExpression(elc,
"#{ADFRegionNavigationBean.getOutcomeExpression}", String.class, new
Class[] { });
((RichRegion)regionComponent).queueActionEventInRegion(me,
null, null, false, -1, -1, PhaseId.ANY_PHASE);
}
}
public String getOutcomeExpression() {
return outcome;
}

When passing a String to identify the region or nested region component to a


findComponent() method the following syntax can be used (“R1”=region, “R2”=nested
region”, etc…):
 “R1:R2:R3…” – looks for R3 relative to the button initiating the ActionEvent. This
syntax wouldn’t work if the button were located inside R1.
 “:R1:R2:R3…” – always looks for R3 starting from the root of the component tree.
Therefore, this syntax should always work.
For further details on the queueActionEventInRegion(…) method, refer to the Initiate
Control Flow within a Region from its Parent Page pattern document on OTN or the
oracle.adf.view.rich.model.RegionModel class.

ADF Region Interaction 6


Functional

Navigation – regionNavigationListener
An <af:region> regionNavigationListener is used if a containing page or page fragment
needs to identify when navigation occurs within a region. When the page fragment
displayed within a region changes an oracle.adf.view.rich.event.RegionNavigationEvent
is raised. The event provides both the old and new page fragment viewIds. Then the
RegionNavigationEvent triggers the regionNavigationListener EL method reference
specified on the <af:region> tag, if any. Therefore, any application logic required when
the region navigation can be incorporated into its regionNavigationListener.
For example, an <af:region> regionNavigationListener is required if the dynamic region
within an <af:popup> provides the ability to “exit” via navigation flow to task flow
return activities. The regionNavigationListener identifies when the region “exits” so the
<af:popup> can be programmatically dismissed without the user manually selecting its
close icon. Using the employee-update task flow definition below for the region, its
<af:region> regionNavigationListener should programmatically hide the <af:popup> after
executing either the “save’ or “cancel” task flow return activities to exit the task flow
definition.

The regionNavigationListener would be specified on the <af:region> UI component as


shown below.
<af:popup id="popupRegion1" contentDelivery="lazyUncached" launcherVar="source"
eventContext="launcher">
<af:setPropertyListener from="#{source.attributes.employee}"
to="#{pageFlowScope.employeeId}" type="popupFetch"/>
<af:setPropertyListener
from="#{pageFlowScope.PopupDynamicRegionBean.popupTaskFlowId}"
to="#{pageFlowScope.PopupDynamicRegionBean.dynamicTaskFlowId}"

ADF Region Interaction 7


Functional

type="popupFetch"/>
<af:panelWindow id="window" title="Employee Popup">
<af:region value="#{bindings.dynamicRegion1.regionModel}" id="dynam1"
regionNavigationListener="#{pageFlowScope.PopupDynamicRegionBean.navigationListener}"/>
</af:panelWindow>

</af:popup>
The regionNavigationListener Java method would be similar to the following. The
method identifies when the region exists via task flow return activity (“newViewId ==
null”) and then programmatically hides the <af:popup>.

public void navigationListener(RegionNavigationEvent event){


String newViewId = event.getNewViewId();

// null new view id indicates the taskflow has ended


if (newViewId == null) {
RichRegion region = (RichRegion)event.getSource();

// look for the parent popup


boolean found = false;
UIComponent component = region.getParent();
do {
if (component instanceof RichPopup) {
found = true;
} else {
component = component.getParent();
if (component == null) {
break;
}
}

} while (!found);

if (found) {

ADF Region Interaction 8


Functional

// send script to the client to hide the popup


FacesContext context = FacesContext.getCurrentInstance();
Service.getRenderKitService(context,
ExtendedRenderKitService.class).addScript(context,
"var popup = AdfPage.PAGE.findComponent('" +
component.getClientId(context) +
"'); popup.hide();");
}
}
}
For further details on the <af:region> tag, refer to the Oracle ADF Faces <af:region> Tag
Documentation. Example used taken from the Embedding Regions Inside Popup
Windows pattern document on OTN.

Share Data – Task Flow Definition <data-control-scope>


If a region should share all the same application data controls as the task flow of its
parent page or page fragment, the recommended implementation approach utilizes the
task flow definition <data-control-scope> property. By setting the region task flow
definition <data-control-scope> property to “shared” all the same data controls of the
parent page task flow will be used by the region. The task flow definition <data-control-
scope> property can also be set to “isolated” if the data controls of the region should
remain completely separate. Default value of the <data-control-scope> property is
“shared”.
Data controls cannot be shared between two different task flows residing within two
different transactions. If the region and its parent page or page fragment are part of the
same transaction or one/both don’t reside within any transaction, data controls can be
shared. A region can’t share the data controls of another region, only its parent page or
page fragment. However, multiple regions can share the data controls of their same
containing page or page fragment. Also, nested regions can share the data controls of
their parent regions to any depth.
Setting the task flow definition <data-control-scope> property explicitly to “shared”
incorporates the following metadata within a task flow definition source file:
<data-control-scope>
<shared/>
</data-control-scope>

ADF Region Interaction 9


Functional

For further details on the task flow definition <data-control-scope> property, refer to the
Oracle Fusion Middleware Fusion Developer's Guide for Oracle ADF within Section
15.3, "Sharing Data Control Instances".

Share Data – Task Flow Definition Input Parameters


A region cannot directly reference the binding values of its containing page or page
fragment. The same holds true for a containing page or page fragment being unable to
directly reference binding values within a region. In order to share a small subset of
values between the two, task flow definition input parameters can be specified. Task
flow definition input parameters are typically used as a means of sharing a small subset
of data with a region when the values are well known and EL-accessible to the containing
page or page fragment. All primitive value input parameters are passed to a region by
value. All object input parameters are passed to a region by reference. Each time the
ADF task flow within a region is restarted, fresh input parameter values will be passed.
Input parameters are very useful if a regions task flow must be restarted when any of the
values passed to the region change. A regions taskFlow binding Refresh and
RefreshCondition attributes can also be useful to ensure the region will be refreshed and
restarted under the appropriate conditions to accept new input parameter values. When a
taskFlow binding Refresh attribute is set to “ifNeeded”, the region will be refreshed and
restarted automatically whenever an input parameter value changes.
For example, a page might contain a table of employees and a region for enrolling the
selected employee in benefits. Changing the selected employee requires restarting the
benefits enrollment region from the beginning for the newly selected employee.
Therefore, by passing the value of the selected employee as an input parameter to the
region and setting its taskFlow binding Refresh=”ifNeeded” the region will be refreshed
and restarted automatically whenever the selected employee changes.
When object instances are passed as a region input parameter, they will always be passed
by reference. Task flow call activities support overriding the passing of object instance
input parameters by reference to passing them by value. Regions; however, do not
provide the same override capability. Therefore, if the region updates a mutable object
instance after it’s passed as an input parameter, the updated object instance values will be
visible to the parent page or page fragment. Likewise, any updates to the passed object
instance by the parent page or page fragment will then be automatically reflected back
within the region without restarting the corresponding ADF task flow. Using this
approach, care should be taken to ensure values passed by reference are updated
appropriately. This is not a recommend approach to pass values back to the parent.
For further details on task flow definition input parameters, refer to the Oracle Fusion
Middleware Fusion Developer's Guide for Oracle ADF within Section 15.2, "Passing
Parameters to an ADF Bounded Task Flow" and Section 16.1.7, "What You May Need to
Know About Refreshing an ADF Region".

ADF Region Interaction 10


Functional

Share Data – Contextual Framework Events


Contextual framework events are often used for notifications between an ADF region and
it’s containing page or page fragment. It’s also possible for a contextual framework
event to include a payload of data to share. Contextual framework events are
recommended if the ADF region interaction use case fits the following two conditions:
 Notification occurs after the regions corresponding ADF task flow has started
 Changes in any data shared by the notification shouldn't restart the regions
corresponding ADF task flow
For example, a page might contain a region providing a 360-degree customer view. The
regions page fragment displays a separate tab for the customers products purchased,
support calls, and contact information. A second region on the same parent page provides
a tree to display one of the three tabs within the 360-degree customer view region. If the
“Support Calls” node in the tree is selected, the 360-degrees customer view region will
display the Support Calls tab. The 360-degree customer view regions task flow isn’t
restarted with a new customer. It simply responds to a contextual framework event to
display a specified tab.
Contextual framework events can be raised by the execution of action bindings, method
action bindings, value attribute bindings, tree bindings, table bindings, or list bindings.
The table below describes when each binding type raises contextual framework events.
Binding Type When Contextual Framework Event Raised
Action and MethodAction Bindings Contextual framework event is raised when the action or meth-
od is executed. Method result forms the contextual framework
event payload of data to share.
Value Attribute Bindings Contextual framework event is raised after the attribute is set
successfully. Can also be triggered by navigational changes.
Range Bindings (Tree, Table, List) Contextual framework event is raised after the currency change
has succeeded. Can also be triggered by navigational changes.

Once raised, contextual framework events are passed to their binding container for
dispatch. The binding container’s contextual framework event dispatcher checks the
event map defined within the binding containers page definition file for interested
consumers. After checking the same binding container where the contextual framework
event was raised, event propagation is then delegated to check for consumers within the
parent binding container event map. This process continues until the topmost parent
binding container is reached. After the topmost binding container is reached, the
contextual framework event is then dispatched to child region binding containers to check
event maps defined with an event producer set to wildcard "*". If interested consumers
are identified, the contextual framework event is delivered to the consumers at the end of
the ADF lifecycle. Contextual framework events are always consumed by methods.

ADF Region Interaction 11


Functional

Event Producer
Contextual framework events are produced by page definition action bindings, method
action bindings, value attribute bindings, tree bindings, table bindings, or list bindings. In
the example below, the queueHelpTopic event is defined within the setHelpId
methodAction binding. When the methodAction binding is executed, the contextual
framework event will be raised. The methodAction passes in a “usage” parameter and
returns a corresponding HelpId value. The HelpId methodAction result will be placed
within the contextual framework event payload and passed along to any event consumers.
<methodAction id="setHelpId"
InstanceName="LookupServiceAMDataControl.dataProvider"
DataControl="LookupServiceAMDataControl"
RequiresUpdateModel="true" Action="invokeMethod"
MethodName="setHelpId" IsViewObjectMethod="false"
ReturnName="LookupServiceAMDataControl.methodResults.setHelpId_LookupServiceAMDataC
ontrol_dataProvider_setHelpId_result">
<NamedData NDName="usage" NDValue="CREATE_PROFILE"
NDType="java.lang.String"/>
<events xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
<event name="queueHelpTopic"/>
</events>
</methodAction>

The setHelpId method executed by the methodAction binding might be similar to the
following:

public Long setHelpId(String usage){


ViewObjectImpl helpVO = this.getHelpTranslations();
ViewCriteria vc = helpVO.createViewCriteria();
ViewCriteriaRow vcr = vc.createViewCriteriaRow();
vcr.setAttribute("HelpUsage", "=" + usage);
vc.addElement(vcr);
RowIterator helpItr =
helpVO.findByViewCriteria(vc, -1,
ViewObject.QUERY_MODE_SCAN_DATABASE_TABLES);
Row helpRow = helpItr.first();

ADF Region Interaction 12


Functional

return (Long)helpRow.getAttribute("HelpId");
}

Event Map
Contextual framework event maps relate together the producer and consumer of a given
event. The consumer handler will be a specified method. If the producer or consumer is
not contained within a region, the “region” attribute is not needed within the event map
<producer> and <consumer> elements. In the example below, the eventMap relates the
queueHelpTopic event producer to its consumer. The producer is identified as any
region. The consumer is identified as the helpPageDef.findHelpTextById method
binding within the helptaskflow1 region. The helpTopicId parameter of the consumer
method is assigned the value of the contextual framework event payload passed from the
producer.
<eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
<event name="queueHelpTopic">
<producer region="*">
<consumer region="helptaskflow1"
handler="helpPageDef.findHelpTextById">
<parameters>
<parameter name="helpTopicId" value="${payLoad}"/>
</parameters>
</consumer>
</producer>
</event>
</eventMap>
Instead of manually creating page definition event map metadata, the JDeveloper Event
Map Editor can also be used to greatly simplify the procedure. To access the Event Map
Editor, add an eventMap element to a page definition in JDeveloper. Then in the
eventMap element Property Inspector select the Edit toolbar button.

ADF Region Interaction 13


Functional

The Event Map Editor dialog will be displayed to Edit an existing event or Add a new
event within the event map.

After selecting the Event Map Editor Edit or Add toolbar buttons, the Modify Event Map
Entry dialog is displayed. It makes modifying or creating event map metadata easier by
using dropdowns for the selection of the event, its producer, and its consumer. The
dropdowns incorporate values from the current page definition, but also the page
definitions of any child regions. The dropdowns; however, currently don’t incorporate
values from any dynamic regions. Those must be entered manually.

ADF Region Interaction 14


Functional

Event Consumer
The contextual event consumer will always be a method. Parameter values of the method
can be assigned by the event map using the contextual framework event payload. In the
example below, the contextual framework event consumer is the findHelpTextById
methodAction binding. It passes in a helpTopicId and returns the corresponding
HelpText. The value of the helpTopicId parameter is assigned within the event map as
the value of the contextual framework event payload. The value of the payload was set
when the event was raised by the result of the producer method.
<methodAction id="findHelpTextById"
Action="invokeMethod" MethodName="findHelpTextById"
IsViewObjectMethod="false"
DataControl="LookupServiceAMDataControl"
InstanceName="LookupServiceAMDataControl.dataProvider"
ReturnName="LookupServiceAMDataControl.methodResults.findHelpTextById_LookupServiceA
MDataControl_dataProvider_findHelpTextById_result">
<NamedData NDName="helpTopicId" NDValue="" NDType="java.lang.Long"/>
</methodAction>

The findHelpTextId method identified as the event consumer might be similar to the
following:

public String findHelpTextById(Long helpId){

ADF Region Interaction 15


Functional

ViewObjectImpl helpVO = this.getHelpTranslations();


ViewCriteria vc = helpVO.createViewCriteria();
ViewCriteriaRow vcr = vc.createViewCriteriaRow();
vcr.setAttribute("HelpTranslationsId", "=" + helpId);
vc.addElement(vcr);
RowIterator helpItr =
helpVO.findByViewCriteria(vc, -1,
ViewObject.QUERY_MODE_SCAN_DATABASE_TABLES);
Row helpRow = helpItr.first();
return helpRow.getAttribute("HelpText").toString();
}

For further details on implementing contextual framework events, refer to the Oracle
Fusion Middleware Fusion Developer's Guide for Oracle ADF within Section 26.5,
"Creating Contextual Events". Example used taken from the Oracle Fusion Store Front
Demo Application.

Share Data – Region Capabilities


Region capabilities can be used by a parent page to identify the current outcomes
available based on a regions current state. The current capabilities of a region might
dictate how the parent page responds (e.g.: displaying or enabling different icons and
buttons).
In the following example, the “Employees” and “Departments” buttons on the parent
page navigate between the Employees and Departments view activities within the region.
Based on the regions current state, either the “Employees” or “Departments” button
should be disabled. For this to occur automatically, the buttons are assigned a region
capability EL Expression for their disabled property.

ADF Region Interaction 16


Functional

When each button is selected, the queueActionEventInRegion(…) method is executed to


initiate the corresponding “employees” or “departments” outcome within the region.
Once the region navigates to the new view activity, the buttons respond automatically by
disabling as appropriate based on the regions state change.

Region capabilities require the availability of the specified regions regionModel through
an EL Expression. An EL expression should never access bindings in any binding
container other than the current binding container (e.g.: #{bindings.taskflowdefinition1}).
Therefore in cases where a regionModel cannot be reached within the current binding
container (e.g.: nested regions), region capabilities cannot be used. This is because a
nested regions nested binding container might not exist yet or might have already been
released.

ADF Region Interaction 17


Functional

The region capabilities APIs reside within the oracle.adf.view.rich.model.RegionModel


class. It consists of the following methods:
Region Capabilities Method Description
getCapabilities() Returns the set of outcomes (capabilities) available based on
the current state of a given region. Each region capability is
represented as a String.

EL Expression syntax:
#{bindings.taskFlowBinding.regionModel.capabilities}

EL Expression returns “true” if the outcome specified is avail-


able based on the given regions current state:
#bindings. taskFlowBinding.regionModel.capabilities['outcome']}
getActions() Returns the list of valid RegionActions based on the current
state of a given region. A RegionAciton is a combination of the
outcome and display name of the associated control flow case.
There will be a corresponding RegionAction outcome for every
outcome returned by getCapabilities().

EL Expression syntax:
#{bindings. taskFlowBinding.regionModel.actions}

In the example described previously, the “Employees” button disabled attribute was
assigned the region capabilities EL Expression shown below. It disables the
“Employees” button if the “departments” outcome is currently available within the
taskflowdefinition1 region (i.e.- the “Departments” button should be enabled and the
“Employees” button disabled).
<af:commandButton text="Employees"
disabled="#{bindings.taskflowdefinition1.regionModel.capabilities['departments']}" />
For further details on region capabilities, refer to the Initiate Control Flow within a
Region from its Parent Page pattern document on OTN or the
oracle.adf.view.rich.model.RegionModel class.

ADF Region Interaction 18


Functional

Related Patterns
 Embedding Regions Inside Popup Windows
 Initiate Control Flow within a Region from its Parent Page

Related Documentation
Documentation Related to the Pattern Artifacts
Task Flow URL View Activities Section 14.3, "Using URL View
Activities" in the Fusion Developer's
Guide for Oracle ADF
Task Flow Parent Action Activities Section 14.9, "Using Parent Action
Activities" in the Fusion Developer's
Guide for Oracle ADF
<af:region> Tag Oracle ADF Faces <af:region> Tag
Documentation.
Task Flow Definition <data-control- Section 15.3, "Sharing Data Control
scope> Instances" in the Fusion Developer's
Guide for Oracle ADF
Task Flow Definition Input Parameters Section 15.2, "Passing Parameters to an
ADF Bounded Task Flow" in the Fusion
Developer's Guide for Oracle ADF
taskFlow Binding Refresh and Section 16.1.7, "What You May Need to
RefreshCondition Attributes Know About Refreshing an ADF Region"
in the Fusion Developer's Guide for Oracle
ADF
Contextual Framework Events Section 26.5, "Creating Contextual
Events" in the Fusion Developer's Guide
for Oracle ADF
RegionModel oracle.adf.view.rich.model.RegionModel
class

ADF Region Interaction 19

Você também pode gostar