components are scattered across Taskflows (in which case you cannot use the declarative support and the programmatic approach is suddenly very hard)?

Fortunately, ADF has a solution: Automatic Partial Page Rendering (or Auto PPR). If you have used ADF with Business Components, you might have seen or used it already, but it is less obvious that you can also use it with ordinary Beans or Bean DataControls.

Using Business Components

With ADF Business Components this is almost too easy. The ADF BC DataControl automatically maintains per Attribute a list of View Components that use/display it. It also keeps track of changes in attributes. The only thing you need to do is tell it that it should use this information for Auto PPR, using one simple property: ChangeEventPolicy in the PageDef. You can set it on an attributeValues binding. In that case only changes from that particular attribute will be propagated automatically, for example:

Using ordinary Beans or Bean DataControls

As explained above, ADF Business Components automatically maintains a list of consuming Components and keeps track of changes, but your Bean – being a Plain Old Java Object – obviously does not. Suppose we want to create the following “application”:

Whenever someone enters a first name or a last name, the full name updates. When the full name updates (whenever someone enters something in any of the name fields) the bottom label also updates to reflect the new full name. This would be very easy using partialTriggers if it weren’t for the fact that the name fields are in a separate Taskflow. This Taskflow is included in a region on the page that contains the “Enter a bio for <FullName>” label.

This example is obviously made up for this blogpost, but situations like this are quite common. It is not hard to imagine that you would want to reuse the logic to enter a person’s name, but also use the person’s full name in other parts of the application. You don’t know (in the context of the “Name details” Taskflow) all the components in other parts of the application that depend on the full name. In fact you don’t want to know, because that would rather defeat the purpose of the Taskflow (i.e. reuse and modularization). So the programmatic approach is also not an option.

The basis of the implementation is a DataControl based on the following bean (not yet including the Auto PPR logic):

Whenever getFullName() gets called we want to remember the consumer (JSF Component) that requested it.

Whenever setFullName(String) gets called we want to do a partial update of all the components that we remembered from step 1.

This sounds easy and it also turns out to be easy. We can reuse the part of the ADF framework that does this for ADF BC. Using a small utility class (AutoPPRSupport.java) I created for this occasion, the only thing we have to do is add a new member to our bean...

... and that’s it! Now, whenever you use the fullName attribute in a JSF Component, it will automatically update when needed. Download the example.

In this particular case we don’t have any rows, so we don’t have to tell the framework which specific row was updated. I leave it as an exercise for the reader to work that one out (hint: using primary keys).