Revisiting Contextual Event : Dynamic Event Producer, Manual Region Refresh, Conditional Event Subscription and using Managed Bean as Event Handler

In this post I'm talking about a couple of features centered around Contextual Event that you might not have cared about ;)
  • You can programmatically add contextual event definitions, register the event producer and even trigger the contextual event. This is useful when you build taskflows which needs to trigger different events based on the context(client that hosts the task flow) where its used. See the below code snippet:
//The following is inside a managed bean, ideally part of 
//some event handling method
DCBindingContainer bc = (DCBindingContainer) BindingContext.getCurrent().getCurrentBindingsEntry();
bc.getEventDispatcher().queueEvent(new CustomEventProducer(), someCustomEventPayLoad);
bc.getEventDispatcher().processContextualEvents();
  • Event producer class( CustomEventProducer ) used in the above code snippet is here:
import oracle.adf.model.events.EventProducer;
public class CustomEventProducer implements EventProducer {
    public CustomEventProducer() {
        super();
    }
    public String getId() {
        return "JDemoEvent";
    }

    public ArrayList getEventDefinitionsList() {
        ArrayList eventDefList = new ArrayList();

        EventDefinitionImpl demoEvent = new EventDefinitionImpl();
        demoEvent.setEventName("JDemoEvent");
        eventDefList.add(demoEvent);
        return eventDefList;
    }
        
}
  • To turn off automated region refresh while consuming contextual event, add refresh="false" for the consumer element in the eventMap present in the consuming page's page definition file. This is useful if you want to take the charge of refresh (or more control on page refresh) for the event consuming page. An example is here:
<eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="JDemoEvent">
            <producer region="*">
                <consumer region="" handler="EventHandlerMethod" 
refresh="false">
                    <parameters>
                        <parameter name="eventPayLoad" 
value="#{data.payLoad}"/>
                    </parameters>
                </consumer>
            </producer>
        </event>
    </eventMap>
  • You can have manged bean as event handler for contextual event(not only data controls). However in this case you may want to create the methodAction bindings manually. This eases your job when you want to refresh UI component or invoke some managed bean code as part of contextual event. The following is an example:
  <bindings>
     
        <methodAction DataControl="AppModuleDataControl" id="EventHandlerMethod" InstanceName="${backingBeanScope.EventHandler}"
                      MethodName="handleEvent">
            <NamedData NDName="eventPayLoad" NDType="java.lang.Object"/>
        </methodAction>
    </bindings>
    <eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
        <event name="JDemoEvent">
            <producer region="*">
                <consumer region="" handler="EventHandlerMethod" refresh="false">
                    <parameters>
                        <parameter name="eventPayLoad" value="#{data.payLoad}"/>
                    </parameters>
                </consumer>
            </producer>
        </event>
    </eventMap>
  • You can turn off a subscriber region from consuming specific instance of contextual event by EL binding the handleCondition attribute present in the consumer region element inside the eventMap in the page definition file. Following code snippet illustrates this item:

<eventMap xmlns="http://xmlns.oracle.com/adfm/contextualEvent">
 <event name="JDemoEvent">
 <producer region="*">
  <consumer region="" handler="EventHandlerMethod" refresh="false"
    handleCondition=
      "#{backingBeanScope.EventHandler.enabledForSubsrcibingEvent}">

Download
You can download the sample work-space from here.
[ Runs with Oracle JDeveloper 12.1.2.0.0 or higher + HR Schema ].
  • Run the main.jsf, it has tow regions, top one that produces the contextual event on clicking the button and bottom one which consumes the event. The event and payload is added dynamically here. 
  • See the EventProducer and CustomEventProducer classes in the ViewController project to get a feel of the dynamic event producer part.
  • See consumerPageDef.xml (page definition file for consumer.jsff) to understand how managed bean can be used as event handler.
  • In consumerPageDef.xml  you may also notice that the event subscription part has a  handleCondition="#{backingBeanScope.EventHandler.isEnabledForEvent}" added. This is used to conditionally turn off the event subscription. Note that, in this example event producer sets some 'family' name to a request scoped map, which is used by the event subscriber by EL binding the handleCondition attribute (which is present in consumer region inside the eventMap element in the page def xml) with EventHandler::isEnabledForSubsrcibingEvent() method to decide whether to subscribe for the event or not. In the sample application, the check-box in the producer UI is used to turn OFF the subscriber region. See the code to get a feel of this implementation. You can have better logic in you application.

Comments