ADF: (re-)Introducing Contextual Events in several simple steps

0

Communication between taskflows and pages, beans and other components in ADF Faces applications is in many cases ideally implemented using contextual events. These events are published from a producer component – a page, taskflow or associated bean – and made available to all interested parties. Events are handed over by the ADF run time infrastructure to any registered consumer in the current scope. This includes any taskflow or enclosing page which has been configured as such. This publish/subscribe model helps achieve interaction and reuse in a decoupled way. I like the principle. I have applied it on several occasions. And today I needed it again in a WebCenter Portal application with custom ADF 11g components. And once again I could not remember exactly how to implement the contextual events, the publication and subscription. This article therefore is primarily for me – so I can quickly recall how to do this in similar subsequent situations. However, if it is useful to you too, that is even better!

The use case discussed in this article is as follows:

image

The section in the red rectangle is a taskflow that has been embedded as a region in the page. This taskflow has indicated that it is capable of consuming contextual events of type SaveEvent. What exactly it will do with such events is not fully disclosed (this example is taken from a use case where the taskflow has functionality to perform special validation of the values entered in the taskflow’s form). The enclosing page has a button in it. When that button is pressed by the user, the associated code will publish a Contextual Event of the type SaveEvent. The ADF runtime infrastructure takes this event and invokes the event consumer in the taskflow. Without knowing more about the taskflow than the fact that it listens to SaveEvents, the developer of the page could hook up the button with whatever action the taskflow will perform based on the event.

This article describes the few quick steps required to accomplish this and also provides a simple ADF application to download.

Creating the Taskflow

The taskflow consists of a single page fragment – detailsPage.jsff. It shows three values taken from the pageFlowScope bean detailsBean. It also shows the value of the input parameter that is passed into the taskflow.

image

The taskflow itself is configured with a single input parameter

image

and a single bean – detailsBean:

image

This bean is extremely simple. Three properties with getters and setters and a single method – process() – that could be quite spectacular but is in fact very straightforward:

image

Declaring the taskflow’s interest in the SaveEvent

The interest in the SaveEvent in this taskflow – or more specifically, in the detailsPage.jsff – is declared in the Page Definition for this fragment.

image

The eventMap element contains entries for each event that this fragment is capable of consuming. In this case, only events that have been published as “SaveEvent” are subscribed to. It does not matter who is the producer of the event – hence the region=”*” setting. When the SaveEvent has been published, it should be propagated to the handleEvent method binding – as is specified through the handler attribute on the consumer element.

The handleEvent method binding has been configured in the Page Definition file for the method handleEvent on the Data Control EventHandlerBean.

image

This Data Control has been created for a POJO called EventHandlerBean, a simple class with a method handleEvent that sort of processes the event:

image

when the event is detected, the ADF Framework will call the handleEvent method on an instance of the EventHandlerBean – passing the event’s payload to the payload input parameter of this method. The method gets hold of the pageFlowScope managed bean detailsBean and invokes its process() method – apparently the appropriate action in this taskflow in response to the SaveEvent.

image

 

Publishing the SaveEvent

The subscription and processing side of the Contextual Events story was described above. The question to be answered next is: how do we publish SaveEvent instances? There are several ways to publish events – some are entirely declarative. All use bindings in the Page Definition file of a taskflow or page in whose context the event should be published. The cleanest, purely programmaitc approach, is discussed here.

A POJO is created – a simple class with a simple method that returns an Object that will be the payload for the event.

image

This class – EventPublisherBean – is exposed as a Data Control, through the same action as was applied to the EventHandlerBean.

image

When we want to publish the contextual event SaveEvent, we can create a MethodBinding in the current PageDefinition for the publishEvent method on this Data Control. We can then invoke this method binding from a page component or from custom logic in some managed bean. In this example, the page that contains the taskflow discussed above also contains a button. When this button is pressed, we want the SaveEvent to be published. The button has an actionListener:

image

The referenced bean – parentBean – is defined in the adfc-config.xml file in this application:

image

The class ParentBean is a POJO. It has two properties and the method buttonPressedEvent that is the action listener for the button in the page.

image

The buttonPressedEvent method locates the operation binding publishEvent in the current Binding Container. This will turn out to be based on the method binding of the publishEvent method on the EventPublisherBean Data Control that we have seen before. This method returns the payload object that is passed into it. At that point, the ADF framework kicks in to actually publish the SaveEvent. It is triggered to do so by the event element that is configured inside the method action in the PageDefinition file:

image

this configuration of events and event inside the method action instruct ADF to publish a contextual event of type SaveEvent whenever the publishEvent method action is invoked. The result of the method action is to be used as the payload for the SaveEvent – and will therefore be passed to all subscribed event handlers.

The above structure is visualized in the next figure:

image

 

When the parentPage.jspx is run, the user can press the button and the taskflow is notified of the SaveEvent, allowing it to take appropriate action. All very loosely coupled. Note: if the taskflow would not be interested in the SaveEvent, the button press would still cause it to be published, but to no avail.

 

Resources

Download the JDeveloper 11gR1 PS5 application with the code discussed in this article: taskflowRefreshTest.zip.

Share.

About Author

Lucas Jellema, active in IT (and with Oracle) since 1994. Oracle ACE Director for Fusion Middleware. Consultant, trainer and instructor on diverse areas including Oracle Database (SQL & PLSQL), Service Oriented Architecture, BPM, ADF, Java in various shapes and forms and many other things. Author of the Oracle Press book: Oracle SOA Suite 11g Handbook. Frequent presenter on conferences such as JavaOne, Oracle OpenWorld, ODTUG Kaleidoscope, Devoxx and OBUG. Presenter for Oracle University Celebrity specials.

Leave a Reply