ADF Faces and Trinidad renderkits…

Looks like there is a confusion about the renderkits for Trinidad and ADF Faces. Today a colleague asked me what’s up with these renderkit IDs:

  • oracle.adf.core
  • oracle.adf.desktop
  • oracle.adf.pda
  • oracle.adf.rich

The last one (oracle.adf.rich) is the one that you want to use, when running ADF Faces Rich Client (checkout the demo: http://tinyurl.com/adf-faces-live) – However JDeveloper takes care of the faces-config.xml set up.

The first three are legacy IDs from ADF Faces 10g. Once the project was donated to Trinidad the IDs have been changed. When you are running Trinidad, you want to use the (previously oracle.adf.core) in your faces-config.xml file:

<faces-config>
...
  <application>
    <default-render-kit-id>
   org.apache.myfaces.trinidad.core
    </default-render-kit-id>
...

If you are interested about ADF Faces 10g to Trinidad migration, checkout this helpful document.

Skinning

Now these other IDs, used for Skinning, are also now namespaced under the “org.apache.myfaces.trinidad” ID:

  • org.apache.myfaces.trinidad.desktop
  • org.apache.myfaces.trinidad.pda
  • org.apache.myfaces.trinidad.core

So when you now create your own skin, use one of the above to point to a specific RenderKit. A quick example on of doing own skinning for (mobile) Trinidad applications is written here.

Client side logging with JavaScript and ADF Faces

ADF Faces is using (on the server) a “wrapper” around the standard Java logging. Based on the given log-level, the server-side console “prints” out different messages. To make life (and debugging) easier we did a similar thing for the client-side: ADF Faces contains a rich client-side Logger API. In order to use it, you need to enable it inside of the web.xml file, like:

<context-param>
 <param-name>oracle.adf.view.rich.LOGGER_LEVEL</param-name>
 <param-value>WARNING</param-value>
</context-param>

Now you can also start to use the LOGGER API in your custom JavaScript code, like:

AdfLogger.LOGGER.logMessage(AdfLogger.SEVERE, "This is from your logger!");

This is really a nice feature. When running with Firebug, you see the messages inside of the FB console!

Nice inline JavaScript and CSS via ADF Faces resource tag

Sometimes it is required that you need (or want) to write some custom JavaScript (and/or CSS). In JSF2 there are two tags to refer to JavaScript and CSS files. While the functionally to seamlessly integrate (external) resources, not always you really want to create an external file for that stuff…

ADF Faces has a nice <af:resource> tag which gives you a good amount of flexibility to write embedded JS. Sure you can also reference to external files as well:

<af:resource type="javascript">
function myJavaScriptFunction()
{
// do stuff in here...
}
...
</af:resource>

This is pretty nice, since you can edit stuff inside of the page. If you figure the CSS (or JavaScript) is getting bigger and bigger, you can always stick it into an external file and reference it with the source attribute of the <af:resource> tag.

Mobile Development with Apache MyFaces Trinidad

Since smartphones, like iPhone or Android phones, are getting more and more popular, more companies are getting serious about a “mobile strategy”. JavaServer Faces is a natural fit, since it’s rich component model allows you to simply switch the renderer… Yes you could introduce new tags/components for that, but’s that for sure an anti-pattern.

Apache MyFaces Trinidad is offering “mobile” support for a bunch of interesting devices, including Android, Microsoft Windows Mobile 5 and 6, or Apple’s iPhone. When companies want to offer a mobile version, they don’t just want “modern” phones… Consumer phones are still common and therefore used by potential customers. However supporting the wide range of different phones is not trivial: Some phones support JavaScript with Ajax, some without… Some have no JavaScript, some have a bad performance etc. All not to easy to deal with, when you have to do it from scratch!

The Apache MyFaces Trinidad renderkit covers that for your convenience, since it handles JavaScript free fallback during mobile rendering! Basically Trinidad assigns the JavaScript capability for a few mobile user-agents to ‘none’ in their capability files (Trinidad maintains a capability file for each/several user-agents). Fellow committer Mamallan is describing technical details here, on a thread to discuss “Apache MyFaces – JS free JSF” for Google Summer of Code.

Not only the capability of JavaScript is different, the size of the screen and the (native) look-and-feel differ as well. To archive a nice and almost native way of rendering ONE PAGE on different phones, (mobile) web developers use the the Skinning facility of Trinidad. Users/Developers have to create phone specific CSS files (every SDK has a tutorial for that, like Apple for its iPhone). Trinidad is able to switch the Skin during runtime. So you could use an EL and some code to attach the right skin, via user-agent detection.

Besides the device-specific CSS creating (and detaching) a custom skin is fairly easy. In the trinidad-config.xml you have the following:

<skin-family>#{agentUtil.phoneFamily}</skin-family>

The trinidad-skins.xml file, which contains would look like:

...
<skin>
<id>iphone</id>
<family>iphoneFamily</family>
<render-kit-id>org.apache.myfaces.trinidad.desktop</render-kit-id>
<style-sheet-name> iPhone/iPhone.css </style-sheet-name>
</skin>
...

While the “phoneFamily()” method in the underlying JavaBean would do something like:

public String getPhoneFamily()
{
FacesContext fc = FacesContext.getCurrentInstance();
HttpServletRequest req =
(HttpServletRequest)fc.getExternalContext().getRequest();
//Get the User Agent string from the browser
String agent = req.getHeader("User-Agent");
// Prints out user agent.  Comment out the line below for production system
if (agent != null && agent.indexOf("iPhone") > -1)
{
// If iPhone is returned.
// Comment out the followling line for production system
return IPHONE_SKIN;
 }
...

Tipp: You can ship your skins in a JAR, so that multiple (mobile) applications could benefit from the work!

Once that all is done, you are good to go! The source code of the JSPX/XHTML pages look like regular Trinidad pages! No new tags/components are required! That’s a good news, since you can leverage the knowledge you gained.

So to give an idea how rich your page could look on different phones, below are some screenshots:


This screenshot has also some information about the Trinidad TAGs that are used.

There my iPod touch and my (old ;-) ) Nokia phone:

The both show the same page, just with a different style sheet. The JSPX page is not different. All the magic is done by the Trinidad Skinning-Engine.

The ADF mobile team at Oracle put together a nice tutorial, which contains a decent demo application. It includes already some Skinnings for different mobile phones. So the getting started is fairly simple with that demo! The Trinidad developers guide has also some resources on mobile JSF development.

Generally the Trinidad library offers a pretty decent and stable framework-core (besides the 100+ components). Without its rock-solid architecture doing mobile applications would be way more odd (or complicated)!

Enjoy!

Pushing realtime updates for your backend to ADF Faces

Imagine you have some services which frequently triggers your backend to process some data and you need to display these changes on the UI… The most reasonable pattern is using Comet!

ADF Faces has great and flexible support for Comet with its ADS facility. This post quickly describes you to push data from a backend to your client. In order to avoid writing and faking a “busy” backed, I use the twitter update stream – which actually provides data in REALTIME to your application.

The previous blog described the pattern how to connect to the Twitter streaming, by using Apache Wink (a REST client API).

Now within the “while loop” you need to notifiy ADS that a new tweet is waiting to be displayed by the client, like:

while(condition)
{
 // parse the input stream's JSON to nick, tweetMsg etc

 listener.onTweet(new TweetBean(nick, image, tweetMsg));
}

So from the “Twitter backend” you notify a listener that a new tweet arrived on the realtime twitter stream.

The easiest way to combine Twitter and ADS is by using the “Proxy approach”. Let your own ActiveCollectionModelDecorator class implement an interface such as “ITwitterUpdateListener”.  So, the above “listener” is actually this class. The code for the onTweet() finally creates and submits the ADS event(s):

public void onTweet(TweetBean tweet)
{
 // start the preparation for the ADS update
 atm.prepareDataChange();

 // create an ADS event.....
 // this class is not part of the API
 ActiveDataUpdateEvent event =
 ActiveDataEventUtil.buildActiveDataUpdateEvent(
// type of the event
 ActiveDataEntry.ChangeType.INSERT,
// the changeCount
 atm.getCurrentChangeCount(),
// rowKey
 new Object[] {tweets.indexOf(tweet)},
// insert at ...
 new Object[] {tweets.indexOf(tweet)-1},
// attribute/property names that change
 new String[] {"image", "nick", "message"},
// the payload for the above attributes
 new Object[] {
tweet.getImage(),
tweet.getNick(),
tweet.getMessage() }
 );

 // deliver the new Event object to the ADS framework
 atm.notifyDataChange(event);
}

Now you can use the <af:table> component to display the information of the tweets. In the example, we show the name and the picture of the poster and the
actual tweet message:

<af:table value="#{bean.activeCollectionModelDecoratorImpl}"
var="tweet" id="t1" ...>

 <af:column width="50" id="c2">

<af:outputText  escape="false"
value="#{tweet.image}" id="ot2"/>

</af:column>

<af:column headerText="USER" id="c1">
 <af:outputText value="#{tweet.nick}" id="ot1"/>
 </af:column>
 <af:column width="350" headerText="Message" id="c3">
 <af:outputText value="#{tweet.message}" id="ot3"/>
 </af:column>
</af:table>

Note: For the image we say escape:false as we stream HTML of the actual twitter location. Note that usually this can be dangerous on all outputText (cross site scripting),but here we want it, since it is a fast way to resolve the IMG…

ADF Faces and ADS is a powerful tool and you can observe twitter trends with out issues! However note that on observing twitter trends, you are kinda spammed by the backend… Therefore you need to think about the “load” of information that your user is potentially interested in..

Another interesting example on how to combine Twitter and “real time ADF Faces” is here. However the only thing there that is not really realtime is that the code polls twitter, which is fine since not all features are yet supported by the Twitter Streaming API!

Generally: This can not be used with Twitter only… You could also connect your 11g database nofifications to push data to the UI. Did that with Frank Nimphius for OpenWorld. (Not sure if his blog actually has the demo code).

Enjoy!

Flexible ADS – Combining popups with ActiveDataService

In this post I showed how to create a simple counter, based on the Active Data Service from ADF Faces. This facility works out of the box with components like:

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

However not always this is enough. There are a bunch use-cases where you want more!

One scenario could be that you have a long-running task in the background and when it is finished, you want to inform the user. Ideally you want to show him a popup which contains some information regarding the scheduled task. Let’s take a look how that is possible with ADF Faces.

As the user is most-likely not interested in watching a ticket/counter, we need to use a (hidden) trick. We use an invisible <af:activeOutputText>, which has one child element (<af:clientListener />):

...
<af:activeOutputText id="activecomp"
  value="#{counterBean.state}" visible="false">
    <af:clientListener type="propertyChange" method="activeDataCallback" />
</af:activeOutputText>
...

The <af:clientListener/> is interested in a “propertyChange” event, which get’s triggered when a property of the component changes. So every time an update is send to the client, the invisible component changes one property, here it is the “value” property. So we leverage that “trick” to call our custom JavaScript activeDataCallback() function when an update reaches the client ;-)

As you can tell from reading the JavaScript-Documentation the client-side event class has been modeled after the JSF ValueChangeEvent, but it is slightly different.

So let’s take a look at the required JavaScript:

...
<af:resource type="javascript">
 activeDataCallback = function(event)
 {
    showPopup();
 }
 showPopup = function()
 {
    var popup = AdfPage.PAGE.findComponentByAbsoluteId("demoPopup");
    popup.show();
 }
</af:resource>
...

In this example the callback is not interested in a property of the event argument. It just want’s to show a popup component, which is nested inside of the page:

...
<af:popup id="demoPopup" contentDelivery="immediate">
 <af:dialog closeIconVisible="false" title="Appointments!"
     visible="true" id="d2">

 <af:outputText value="Real content would go here" id="txtBox"/>

 </af:dialog>
</af:popup>
...

The result looks like this, once the active data arrives the client:

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.

Running ADF on different containers

When you download JDev, your application by default runs (and deploys) agains the Weblogic container. However, the ADF framework is running on different containers as well. My colleague Shay Shmeltzer gave me a list of instructions for different containers, today.

Here it is:

* yeah, as of yesterday Glassfish 3 is out. I guess someone will write an instruction for that container in the (near) future as well …

Hope this list helps!

ADF’s Active Data Service and multiple push windows

As mentioned here, the ADS feature of ADF Faces supports “push channel sharing” since a very long time…

The first window that hits a page which contains an active component, e.g. a <af:table> that is referencing to an ActiveDataModel implementation, becames the “master” window. This window maintains a persistent connection to the ADS subsystem. In the screenshot you can see that the first window has a HTTP GET request to a wls.ads resource (this URL is representing our implementation of the AbstractAsyncServlet of Weblogic – yes on other containers this is not invoked… ;-) ).

Notice that the second window does NOT have a connection to that servlet… In fact, when the second page renders, it registers itself with the master window. Once the ADS subsystem receives a new (server-side) event, in streams the data ONLY to the master window. That window simply dispatches the payload to the components (on the right page/window).  Some more on how to talk to a different window, you can read here.

Now you may wonder what happens if you close the master window (or do a refresh/F5 there) ? You are not (totally) loosing the persistent connection. The client side engine of ADS (called Active Data Manager) notices that the master window is going away and migrates the channel to one of the slave windows. That ensures you never loose active data…

This is a pretty cool feature! To play with ADS / ADF just get a copy of JDeveloper.

ADF Faces and Server-Side-Push

Some of you already know that ADF Faces does Server-Side-Push, with its ADS (Active Data Service) facility. It is a very feature rich offering that has cool stuff, under the hood. Over the last release we also improved our documentation.

To mention only a few features, ADS supports HA/fail-over since 2008, but that is unfortunately not (yet) mentioned in the documentation.. Another cool thing is that it doesn’t waste the “open connection limitation” from some browsers, as it shares an “active channel” for the push content. Therefore only one window is “talking” with the server and it basically dispatches the streamed-up content to all registered (slave) windows.

The key concept of the ADS solution is that it is pretty much model driven right now and therefore doesn’t force the page author to do (much) sit-ups… Once you have a working implementation of our ActiveDataModel interface, you get active data for free, with our table component (<af:table value=”#{myBean.activeModelImplementation}” />), for instance. For the last release we also offered a convenience implementation, called the Active Data Proxy. That is a pretty nice option to also connect your existing model (and/or enterprise Java, like JPA) with the ADF Faces Push-Solution (meaning ADS). I will post some examples and use-cases, done with the “proxy” here soon…

By default ADS uses (HTTP) STREAMING as its transport mechanism. However the solution also supports LONG-POLLING and POLLING (periodic polling). For the last release we added the LONG-POLLING support. Before that we offered POLLING (still supported ;-) ) as an alternative transport option, as HTTP-STREAMING can have some issues with (legacy) infrastructure (e.g. HTTP 1.0 proxy-servers). A big benefit is that the used transport-option is transparent for the developer, as the ADS subsystem handles that for you. That means the <af:table> component, for instance, just receives the new data; regardless if ADS does STREAMING, LONG-POLLING or even (periodic) POLLING.

ADS (and ADF Faces, of course) has a ton of cool features. You just need to explore them ;-)

To get started, get a copy of our latest (November 2009) release of JDeveloper and read the documentation :-)