ADF’s Active Data Service and scalar data (like activeOutputText)

I mentioned earlier that ADS is pretty much model driven and requires no extra sit-ups in the declarative view. It supports (currently) the following ADF components:

  • activeCommandToolbarButton
  • activeImage
  • activeOutputText
  • table
  • tree
  • All DVT components

Most examples that are viewable (or documented) provide an introduction on “How to combine ADS with collection-based data”. Let’s take a look on how to use activeOutputText with a Java Bean, as you may not have a model (or BAM).

Imagine a simple page that contains a ticker/counter. On the server-side a counter is updated every n seconds. We will use ADS to stream the data to the client. The part for the activeOutputText component is easy:

...
  <af:activeOutputText
    value="#{counterBean.state}"
    inlineStyle="
      color:brown;font-size:100px;font-weight:bold;text-align:center;
    "
  />
...

The Bean behind the page (counterBean) has a slightly tricky part, where we fake the actual model. In a @PostConstruct method we get access to the current ActiveModelContext and register a model key path for the “state” attribute:

ActiveModelContext context =
  ActiveModelContext.getActiveModelContext();
Object[] keyPath = new String[0];
context.addActiveModelInfo(this, keyPath, "state");

Afterwards we use Java’s ScheduledExecutorService class to schedule the data updates. The updates are done by the triggerDataUpdate() method:

public void triggerDataUpdate()
{
  counter.incrementAndGet();

  ActiveDataUpdateEvent event =
    ActiveDataEventUtil.buildActiveDataUpdateEvent(
      ActiveDataEntry.ChangeType.UPDATE,
      counter.get(),
      new String[0],
      null,
      new String[] { "state" },
      new Object[] { counter.get() });

  fireActiveDataUpdate(event);
}

At the beginning the “counter” is updated and the ActiveDataEventUtil is used to create the ActiveDataUpdateEvent. The complete code for the Bean (which implements a convenience implementation of the ActiveDataModel) is here:

package net.wessendorf.oracle.ads.simple;

import java.util.Collection;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import javax.annotation.PostConstruct;

import oracle.adf.view.rich.activedata.ActiveModelContext;
import oracle.adf.view.rich.activedata.BaseActiveDataModel;
import oracle.adf.view.rich.event.ActiveDataEntry;
import oracle.adf.view.rich.event.ActiveDataUpdateEvent;

import oracle.adfinternal.view.faces.activedata.ActiveDataEventUtil;

public class CounterBean extends BaseActiveDataModel
{
  @PostConstruct
  public void setupActiveData()
  {
    ActiveModelContext context = ActiveModelContext.getActiveModelContext();
    Object[] keyPath = new String[0];
    context.addActiveModelInfo(this, keyPath, "state");

    // setup a timer that queues the events (in a loop)
    ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
    ses.scheduleAtFixedRate(
      new Runnable() {
        public void run() {
          triggerDataUpdate();
        }
      },
      5, // let's wait some seconds
      2, // period between the updates
      TimeUnit.SECONDS);
  }

  public void triggerDataUpdate()
  {
    counter.incrementAndGet();

    ActiveDataUpdateEvent event =
      ActiveDataEventUtil.buildActiveDataUpdateEvent(
        ActiveDataEntry.ChangeType.UPDATE,
        counter.get(),
        new String[0],
        null,
        new String[] { "state" },
        new Object[] { counter.get() });

    fireActiveDataUpdate(event);
  }

  public String getState()
  {
    return String.valueOf(counter);
  }

  protected void startActiveData(
     Collection<Object> rowKeys, int startChangeCount){}

  protected void stopActiveData(
     Collection<Object> rowKeys) {}

  public int getCurrentChangeCount()
  {
    return counter.get();
  }
  private final AtomicInteger counter = new AtomicInteger(0);
}

To enjoy get a copy of our latest (November 2009) release of JDeveloper and read the documentation.

Howdy!

Posted in adf, ajax, comet, fun, java, javascript, jdeveloper, jsf, oracle, Oracle ADF Faces, web²
7 comments on “ADF’s Active Data Service and scalar data (like activeOutputText)
  1. […] Faces has great and flexible support for Comet with its ADS facility. This post quickly describes you to push data […]

  2. kiran pophale says:

    hi,
    can you please tell when setupActiveData() method is called in your example?

  3. matthiaswessendorf says:

    Hi Kiran,

    once the bean has been instantiated, b/c of the @PostConstruct annotation

    • kiran pophale says:

      hi,
      thanks for your reply.
      i have created the application referring your post.
      but it dose not show the counter value in activeOutputText
      how activeOutputText control get updated?

  4. kiran pophale says:

    hi
    i managed to run the code.
    can you please tell me how to stop the thread? i have observed thread is running after undeployement of the application.

  5. kiran pophale says:

    hi
    rotate mean i want to change the source attribute of the activeImage component after some time interval.

    i have done simple demo but it is not working what i expect.

    if possible please correct me where i did mistake

    my jspx file is

    my managed bean is

    package oracle.view.backing;

    import java.util.ArrayList;
    import java.util.concurrent.Executors;
    import java.util.concurrent.ScheduledExecutorService;
    import java.util.concurrent.TimeUnit;
    import javax.annotation.PostConstruct;
    import oracle.adf.view.rich.activedata.ActiveModelContext;
    import oracle.adf.view.rich.event.ActiveDataEntry;
    import oracle.adf.view.rich.event.ActiveDataUpdateEvent;
    import oracle.adfinternal.view.faces.activedata.ActiveDataEventUtil;
    import java.util.Collection;
    import java.util.List;
    import oracle.adf.view.rich.activedata.BaseActiveDataModel;
    import oracle.adf.view.rich.component.rich.output.RichActiveImage;

    public class Untitled1 extends BaseActiveDataModel {
    private RichActiveImage ai1;
    private List lst = new ArrayList();
    Integer globalVal = 0;
    String pathtodis = “”;

    @PostConstruct
    public void setupActiveData() {
    ActiveModelContext context =
    ActiveModelContext.getActiveModelContext();
    Object[] keyPath = new String[0];
    context.addActiveModelInfo(this, keyPath, “state”);
    lst.add(“/u2.jpg”);
    lst.add(“/123simple.jpg”);
    lst.add(“/124simple.jpg”);
    // setup a timer that queues the events (in a loop)
    ScheduledExecutorService ses = Executors.newScheduledThreadPool(1);
    ses.scheduleAtFixedRate(new Runnable() {
    public void run() {
    triggerDataUpdate();
    }
    }, 6, // let’s wait some seconds
    6, // period between the updates
    TimeUnit.SECONDS);
    }

    public void triggerDataUpdate() {
    counter++;
    if (globalVal == 3) {
    globalVal = 0;
    System.out.println(“yes global value has been reseted ” +
    globalVal + ” path ” +
    (String)lst.get(globalVal));
    }
    System.out.println(“triggerDataUpdate ” + globalVal + ” path is ” +
    (String)lst.get(globalVal));
    ActiveDataUpdateEvent event =
    ActiveDataEventUtil.buildActiveDataUpdateEvent(ActiveDataEntry.ChangeType.UPDATE,
    globalVal,
    new String[0], null,
    new String[] { “state” },
    new Object[] { (String)lst.get(globalVal) });
    globalVal++;
    fireActiveDataUpdate(event);
    }

    public String getState() {
    return String.valueOf((String)lst.get(globalVal));
    }

    protected void startActiveData(Collection rowKeys,
    int startChangeCount) {
    }

    protected void stopActiveData(Collection rowKeys) {
    }

    public int getCurrentChangeCount() {
    return counter.intValue();
    }
    private Integer counter = new Integer(0);

    public void setAi1(RichActiveImage ai1) {
    this.ai1 = ai1;
    }

    public RichActiveImage getAi1() {
    return ai1;
    }

    }

    but it dosnt update the source attribute of the ActiveImage when it reaches to the ArrayList last index

  6. Alex says:

    Could you use the same counterBean class to update several activeOutputText in the same page? or you have to create a different counterBeanX class for each activeOutputText in a jspx page?

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: