Thursday, March 13, 2014

JSR 286 InterPortlet communication





Interportlet communication(IPC) allows sharing of data between portlets.
In JSR 168, we use portlet session with Application Scope to share data between portles and this is possible within a portlet application, because session can't be shared across two different context (web/portlet application).


JSR 286 has introduced two ways to achieve IPC.

1) Public Render Parameter
2) Eventing

Let's dicsuss one by one with their Concept, Implementation and Usage Scenario

1) Public Render Parameter

Concept:-
Public Render parameters allows you to share data using render parameters.
Source portlet will set data using actionResponse.setrenderPrameter in processAction phase and target portlet will receive data using renderRequest.getPramete("param name").

Note:- In JSR168 render parameter was also there but not public.
Public means, render prameter set in processAction of one portlet can be retrieved in render method of any other portlets in the same/different war.

Implementation:-
a) You will require to set public render parameter at portlet application level.
List all the render prameter you like to publish/share.

<public-render-parameter>
<identifier>id1</identifier>
<qname xmlns:x="http://sun.com/params">x:param1</qname>
</public-render-parameter>
<public-render-parameter>
<identifier>id2</identifier>
<qname xmlns:x="http://sun.com/params">x:param2</qname>
</public-render-parameter>

b) Need to specify render prameters you would need a portlet to share
Specify prameter within portelts that would like access those prameters

<portlet>
<portlet-name>PortletA</portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
<supported-public-render-parameter>id2</supported-public-render-parameter>
<portlet>
<portlet>
<portlet-name>PortletB</portlet-name>
<supported-public-render-parameter>id1</supported-public-render-parameter>
</portlet>
<portlet>
<portlet-name>PortletC</portlet-name>
<supported-public-render-parameter>id2</supported-public-render-parameter>
<portlet>

Usage scenario:-
a)
Since the public render parameters are encoded in the URL, so you will have option only to share data between portlets of type String and String arrays.
b) Since public render prameter are only available in render methods, so you will not be using it where processing is required in data.
c) Best to use in situations where, you have target portlet changing it's rendering view based on parameter retrieved without any processing on prameter value.

2) Eventing

Concept:-
Portlet event model is a loosely coupled, that allows creating portlets as stand-alone portlets that can be wired together with other portlets at runtime.
Source portlet publish an event and all other portlets ( within same war or different war), can register for that event.
Once target portlet receives an event, it can peform processing on data and then display results based on business need.

Implementation:-

a) Portlet which want to publish events should have follwoing entry at application level in portlet.xml.
If IPC is beween two different war, then this event definition should present in portlet.xml of both war.
Setting event definition.

<portlet-app ...>
<portlet>
. . .
. . .
</portlet>

<event-definition>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
<value-type>com.wps.Employee</value-type>
</event-definition>
</portlet-app>

b) Event publishing Portlet should specify events that they want to publish.

<portlet>
<description>SourcePortlet</description>
<portlet-name>SourcePortlet</portlet-name>
.................
<supported-publishing-event>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
</supported-publishing-event>
</portlet>

Setting an event into processAction of publishing portlet

public class SourcePortlet extends GenericPortlet {
public void processAction(ActionRequest request, ActionResponse response)
throws PortletException,IOException {
QName qname = new QName(""http://ExtremePortal.blogspot.com/Employee" , "Employee");
Employee emp = new Employee();
//set values in Employee
response.setEvent(qname, emp);
}
}


c) Event processing portlets should specify events that they want to process

<portlet>
<description>TargetPortlet1</description>
<portlet-name>TargetPortlet1</portlet-name>
<supported-processing-event>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
</supported-processing-event>
</portlet>

<portlet>
<description>TargetPortlet2</description>
<portlet-name>TargetPortlet2</portlet-name>
<supported-processing-event>
<qname xmlns:x="http://ExtremePortal.blogspot.com/Employee">x:Employee</qname>
</supported-processing-event>
</portlet>

Event process portlet needs to override processEvent method

public class TargetPortlet extends GenericPortlet {
public void processEvent(EventRequest request, EventResponse response) {
Event event = request.getEvent();
if(event.getName().equals("Employee")){
Employee emp = (Employee )event.getValue();
//process emp here
}
}
}

Usage scenario:-
a) Event technique should be used in situation where data shared needs to be processed in receiver portlet.
b) it is advisable to use public render parameters as they avoid the overhead for portlets event creation and wiring the portlets together. Wiring portlets together is portal container specific and is an additional overhead.

2 comments: