Thoughts on business and business software

Mosaic and LiveCycle Data Services

Adobe’s two RIA products – LiveCycle Mosaic and LiveCycle Data Services (LCDS) – go together like peanut butter and jelly. One provides a framework for intuitive, user focused applications, the other provides efficient access to real time back end data. Between the two of them they can provide up-to-date data in an engaging user experience.

There are a couple of different ways to combine the two products, however. What one you will choose will depend on your particular setup and how your back end data is organized. So, do you prefer your jelly on top, or on the bottom?

In this post I’ll present both methods of Mosaic/LCDS integration using an overly simple example. Hopefully this will give you some ideas for your projects.

In the end I built a simple Mosaic application that demonstrated both methods.

The source entry points to my Java class and it uses the existing my-amf channel.

The last thing that I needed to do was to add a crossdomain.xml file to my LCDS server. This is because my Mosaic server is running on a different box.

Jelly on top; Calling LCDS directly from a tile

The first method I’ll show is also the most direct. This involves making a direct call from the Mosaic tile to the LCDS service. This is a useful method when there is a direct relationship between the tile’s visual elements and the data. What it has in simplicity, it lacks in power. This method does not lend itself to decoupling the data from the tile.

Again this is based on the LCDS documentation. There are some concessions to the Mosaic framework however. First, an AMF channel needs to be setup, also several classes need to be registered. I know I’ve registered more than I need, but I will probably expand this tile later on.

As you can see, when the user clicks on the Send button, a function is called that makes use of the remote object. The remote object then uses the AMF channel to make a LCDS call to the POJO. The results are then shown on the screen.

Jelly on bottom; Using a Mosaic service to make the LCDS call

Another way to make an LCDS call from a Mosaic tile would be to use a Mosaic service as an intermediary. In this case the tile wouldn’t be aware of the LCDS service at all, any interactions would be made through the Mosaic service. This is very useful if multiple tiles need to access the same LCDS service as it only needs to be accessed once. It also allows easy decoupling of the tiles and the data as the Mosaic service can be changed without affecting the inner workings of the tiles. The draw back is that it does require a bit more coding and more for thought when planning out the Mosaic service. For more info on creating Mosaic services, see my earlier blog entry

The interface

Let’s look at the code to do something similar to the simple example. First the Interface object:

Since the LCDS call is asynchronous, I needed a getter and setter function to make the request and get the response. I also need a method to determine when the asynchronous call is complete (so I can go get the data). The echoReady function is a bit of a cheat to allow this. As I mentioned in an earlier post, there is no easy way to send a message from the Mosaic service to the tile because the service is not context aware. You can push the context into the service, but for this example it would be overkill. So I built a cheap and cheesy Boolean function that I can ping from the tile.

The final function setLoaderURL is very important to the application and requires a bit of explanation. When I was working on this project, I set everything up as I did with the direct LCDS call. I kept getting an error that the URL was null. I knew I had set the URI for the amf channel, so what was the URL it needed? After discussing it with several of my colleagues I was able to narrow it down to the fact that the LoaderConfig.mx_internal::_url object needs to have a URL to a MXML element. Passing the tile’s loaderInfo.url value to the Mosaic service seems to do the trick.

This is very similar to the direct LCDS call, except it has getters/setters so the calling tile can go and get the resulting data. The amf channel listeners are there as a result of me trying to debug the setLoaderURL issue mentioned above.

The Tile

The tile that uses the service is quite simple. It uses the IHelloWorld interface to make the call and relies on Mosaic to inject the service instance at runtime (see my previous entry for more on how this works):

You may notice that I have a timer that checks to see if the data is returned. This is because the service has no built in way of sending a message to the tile. The timer was a bit of a cheat and I wouldn’t recommend using this method in production code. Instead I would recommend passing the tile context to the service so it can send a proper Mosaic message (see this post for more info)

Conclusion

As you can see from this simple example, there are a couple of different options for combining LCDS and Mosaic. Each has its advantages and weaknesses and it will depend on your situation as to which one to use:

Direct LCDS Call:

Pros:

Simple to code

Direct tie from data to visual elements

Cons:

visual elements not decoupled from tile

each tile makes its own connection – no connection sharing

Mosaic Service LCDS Call:

Pros:

LCDS call abstracted from tile

multiple tiles use same call

Cons:

more complex code

need to implement your own checker for returned data, or pass the tile context to the service