5/27/2011

Inter-Portlet Communication in Liferay with JSF

This little tutorial will show you how to use Inter-Portlet Communication with JSR 286 Events and JSF 2.0.


Some weeks ago I wrote a blog entry about Inter Portlet Communication the way it is meant to be: Events in JSP-based portlets. You can find that post here:


http://liferay-blogging.blogspot.com/2011/03/inter-portlet-communication-in-liferay_26.html

Today, we will use, the same approach for a JSF based portlet.


Sending Portlet


The portlet that wants to send some data to another portlet has to do send the event manually like this (you can do this in a normal action method, whenever you like):

QName qName = new QName("http://your.domain/name","eventname"); 
ExternalContext externalContext = FacesContext.getCurrentInstance() .getExternalContext(); 
ActionResponse actionResponse = (ActionResponse) externalContext .getResponse(); 
actionResponse.setEvent(qName, "This is a test");


Receiving Portlet:


The Portlet that wants to receive the data from the sending portlet has to do the following. First, create a class that subclasses org.portletfaces.bridge.BridgeEventHandler. This class is in the portletfaces bridge, that you need to get JSF 2.0 running in Liferay. When you created the class (we will call it HelloJSFListener), add the following to your portlet.xml:


<init-param>
<name>javax.portlet.faces.bridgeEventHandler</name>
<value>de.test.HelloJSFListener</value>
</init-param>


This will tell our portlet, that whenever an event occurs, that this portlet is subscribed to, notify the HelloJSFListener. Next, add the following configuration line to your portlet.xml:



<supported-processing-event>
<qname xmlns:x="http://your.domain/name">x:eventname </qname>
</supported-processing-event>



Now our listener is ready to do some serious Inter-Portlet Communication! What we need now is to notify our controller class when our listener is called. We can do it like this:

public EventNavigationResult handleEvent(FacesContext facesContext, Event event) { 
EventNavigationResult eventNavigationResult = null; 
String eventQName = event.getQName().toString(); 
if (eventQName.equals("{http://your.domain/name}eventname")) { 
String value = (String) event.getValue(); 
String elExpression = "#{receiver}"; 
ELContext elContext = facesContext.getELContext(); 
ValueExpression valueExpression = facesContext.getApplication().getExpressionFactory()
.createValueExpression(elContext, elExpression,Receiver.class); 
Receiver Receiver = (Receiver) valueExpression.getValue(elContext);
Receiver.setNewValue(value); 
} 
return eventNavigationResult;  }
This piece of code retreives the controller by using standard JSF Expression language. It then sets the received String into a setter using the setNewValue() method. This setNewValue() method in our example does nothing else but set the data. The View will automatically be refreshed - no need to think about that.


One word about AJAX - forget about using Inter-Portlet Communication when you are using the <f:ajax> tag. We need the ActionResponse to fire our event, and when using AJAX, there will be no response.


Download Eclipse Project here: https://rapidshare.com/files/4275130401/JSFIPCPortlet.rar

If you like this tutorial it would be very nice, if you could click on some of the google ads you see on the right side. It helps me run this block and motivates me ;)

If you have any questions, feel free to leave a comment.