Roufid

Liferay JSF IPC using event (Inter Portlet Communication)

Introduction

Once a portlet is placed on a portal page, its data is not directly shared with other portlets. IPC (Inter Portlet Communication) defines the ways that a Portlet can interact and communicate with another Portlet. There are four ways to make inter portlet communication :

In this post, we will see how to communicate between JSF portlets using events.

If you are interested in portlet communication between none-JSF portlets, this article may interest you.

Events

JSR 286 (Portlet 2.0) introduced portlet communication using events. Due to JSF life cycle communication between JSF portlets is made differently in comparison to MVCPortlet.

There is no direct alignement between Portlet event phase and any JSF lifecycle phase. Javax.portlet specification introduced an event bridge to process portlet events. Below steps to follow to make a JSF Portlet communication using events:

The first step is to define the event that will be fired and processed by portlets. The definition is set in the portlet configuration file Portlet.xml. Below the declaration:

Xmlns : Give a namespace to the event
Qname : Give a unique identifier in the namespace
Value-type : Type of object the event will transfere

To handle portlet events, you must create a custom bridge event handler which will process all events fired by portlets that defined it. In fact, you must create a Java class that implements the handleEvent method of javax.portlet.faces.BridgeEventHandler interface as below :

The handleEvent method takes two parameters :

FacesContext : The current instance of the JSF context
Event : The fired event

We will implement this method to process the event in the receiver portlet.

Declare that the sender portlet is publishing the defined event in portlet.xml

To send the event, the portlet must specify that it’s publishing it. Add in portlet.xml file the <supported-publishing-event> property that refers to the event identifier. Example:

Xmlns must be the same as the event definition. Same for the event identifier.

Declare the custom bridge handler in the portlet.xml

The event sender portlet must register the custom bridge event handler that will process the event. To do so, you must give the fully qualified name of the bridge event handler created in the previous section. Let’s consider that it is located in the package : com.roufid.tutorials.bridge. Below the configuration :

Firing the event

Firing event from the sender portlet is done by using QName class that refers to the defined event by giving its namespace and identifier.

Use the same event namespace and identifier given in the portlet.xml.

Declare that the portlet is processing the defined event in portlet.xml

The receiver portlet must declare that it’s processing the defined event by adding the property         <supported-processing-event> in the portlet.xml

Declare the custom bridge handler in the portlet.xml

Same as the sender portlet, the receiver portlet must register the custom bridge event handler. Define the same configuration :

Processing the fired event in the CustomBridgeEventHandler

Processing the fired event is done in the CustomBridgeEventHandler you created previously. Since this CustomBridgeEventHandler is processing all fired events you must distinguish them. To do so, you can check the fired event QName as below :

Now you learned how to communicate between JSF portlets, let’s take a concrete example.

Concrete example

Let’s see a full example of using the JSF IPC using event.


The code source is available on Github. Download the source

Let’s consider two portlets :

JSF portlet communication using event

Defining the event

The first step is to define the event that will be fired and processed by portlets in the portlet.xml file. If the portlets that handle the event are in the same Liferay Plugin Project, so only one definition of the event must be in the portlet.xml file. If not, each Liferay plugin project must declare it in its portlet.xml file.

In this example, the two portlets are in the same Liferay Plugin Project.

The event that will be fired and processed will be called “selectCarEvent” and will store the car identifier which is a java.lang.String. The declaration is as following :

Defining the event handler : CarBridgeEventHandler

Below the bridge that will handle portlet events.

Sender portlet : CarList

Defining the CarList portlet in the portlet.xml file. This portlet will publish the “selectCarEvent” event. It must define the <supported-publishing-event> property :

Firing the event

Receiver portlet : CarInformation

Defining the CarInformation portlet in the portlet.xml file. This portlet will process the “SelectCarEvent” event. It must define the <supported-processing-event> property :

The event is processed in the CarBridgeEventHandler

Rendering after deployment

The CarList portlet is on the left. CarInformation portlet is on the right.

Liferay JSF portlet communication using event – Before choosing a car

Below the result after selecting Ferrari car.

Liferay JSF portlet communication using event – After choosing a car


The code source is available on Github. Download the source