Portlet
Creation Made Easy Part -II
Inter
Portlet Communication using IPC Story Board
Contributed
by Umachithra Damodaran
Jun
2007
The
Inter Portlet communication for Sun Java System Portal Server was
achieved through the proprietary API's which was an extension to
JSR-168 Portlets. Using this API, JSR-168 portlets will be able
communicate with each other even if they are in different web
applications. It is assumed that all these portlets will be on the
same instance of a Portal Server and running inside the Portal Server
Portlet container.
1
Inter Portlet Communication API
1.1
Overview
This
API uses event generation and notification to convey the
information/data among portlets. The event notification will be for
the portlets which have registered themselves for listening to that
particular event.
1.2
Event Generation and Subscription
Inter
Portlet communication consists of an Event Generator Portlet and
Event Subscriber Portlet. The Event Generator portlet triggers an
event through its processAction() method. Portlets interested in
receiving the event(Event Subscriber portlet ) will listen to the
event and perform some action in response to the event.
In
order to listen and respond to the event the Subscriber portlet has
to implement an interface called PortletEventListener. This has the
handleEvent() method ,which will be called if and only if an event is
fired and the portlet has subscribed to listen to that event. The
subscriber portlet can opt to throw a new event from the
handleEvent() method.
In
addition to this, all the portlets which are interested in generating
or subscribing an event must declare it in the sun-portlet.xml file
under <generates-event></generates-event> and
<consumes-event></consumes-event> tag.
2
IPC StoryBoard
The
IPC Story Board provides a drag and drop support for linking the
Event Generator Portlets and Event Subscriber Portlets and generating
the appropriate code for them.
The
IPC StoryBoard currently supports the JSR 168 inter portlet
communication and in future will also support the Eventing feature of
JSR 286.
2.1
Installing IPC Story Board Plugin
Download
the plugin from http://portalpack.netbeans.org/download.html
and
follow the install instructions to install the plugin.
3
Creating Communicating Portlets using IPC Story Board.
The
following diagram depicts the process of linking the Portlets using
Storyboard.

A
Fund Transfer example is taken to show the Inter Portlet
Communication. The FundTransfer Portlet fires an event ,when a
transfer operation takes place.AccountBalance_A portlet consumes the
event fired by FundTransfer Portlet and reduces the balance of
Account A. This in turn fires a new event which is consumed by
AccountBalance_B portlet,which increases the balance with the amount
transferred.
3.1
Create a Event Generator Portlet
1.Create
a new Portlet Application by selecting, New Project ->Portlet
Applications -> JSR 168 Portlet Application in the Netbeans IDE .
2.Enter
the name of the Portlet and other valid data required and click Finish.
3.The
Portlet Application is created with all the files required by the
JSR168 specification for portlet. Now ,if you expand the portlet.xml
file ,you would see all the portlets listed in the application as
nodes. This is a new feature introduced in this plugin.
4.
Edit and update the FundTransfer_view.jsp with the following code:
-
|
<%@ taglib
uri="http://java.sun.com/portlet" prefix="portlet" %>
<portlet:defineObjects/>
<form
action="<portlet:actionURL />" method="POST">
<table border=1>
<tr><td
colspan="2"><b>Internal Funds
Transfer</b></td></tr>
<tr><TD>From Account
No</TD><TD>12345</TD></tr>
<tr><TD>To Account
No</TD><TD>67890</TD></tr>
<tr><TD>Amount</TD><TD><input
type="text" name="amt" size=15></TD></tr>
<tr><TD><input
type="submit" value="Transfer" ></TD></tr>
</table>
</form>
|
5.
Choose the Portal Server on which the portlet application should be
deployed.
a.Select
the Portlet Application under the Projects tab ,right click and choose
properties.
b.Select
the category “Run” and choose the “Open source
Portlet Container Driver” / “Sun Java System Portal
Server 7.x” in the drop down box for “Server” and
click Ok.
3.2
Create the Event Subscriber Portlet
Create
a second portlet called AccountBalance_A ,following the steps
mentioned above.
a.Add
a class variable “ double balance=200000;”
b.update
the doView() method as follows :
-
public void doView(RenderRequest
request, RenderResponse response) throws PortletException,IOException {
response.setContentType("text/html");
PrintWriter writer =
response.getWriter();
writer.println("<h4>Banlance
For Account 12345 is :</h4>"+balance);
}
|
Similarly,
create another portlet called AccountBalance_B and follow the steps
mentioned above and provide a different value for balance.
3.3
Storyboard
Invoke
the storyboard by selecting Window->"IPC Storyboard" option in IDE.
Now select the FundTransfer node ,under the portlet.xml and drag into
the story board. Similarly , drag the AccountBalance_A portlet into the
storyboard.
3.4
Adding an event to the Event Generator Portlet.
Select
the FundTransfer Portlet inside the storyboard and right click and
choose the option “Add Event”. It will create a Event
called “New_Event”.Double click the event created and
rename it as “transfer”.
This
will insert the following tags in the sun-portlet.xml file.
-
<portlet>
<portlet-name>FundTransfer</portlet-name>
<events>
<generates-event>transfer</generates-event>
</events>
</portlet>
|
3.5
Generate the Source for the event
Now
select the event created and right click and choose the option
“Generate Source”. It pops up a window ,where you can
choose to add the source generated inside the processAction method or
in a new method. Choose to add inside the processAction method by
selecting the option “Add to existing source”.
You
will now see that the processAction() is updated with the following
code.
-
|
try{
String eventData = "";
PortletEventBroker peb = new
PortletEventBroker(request);
PortletEvent pe =
peb.createEvent("transfer");
pe.setEventData(eventData);
pe.fire();
} catch(Exception e) {
//TODO Catch Exception here
}
|
Change
line 2 to String eventData = request.getParameter("amt");
3.6
Link the Event to the Subscriber
Select
the event in the FundTransfer Portlet in the storyboard and drag and
drop the event on the AccountBalance_A portlet. This will link the
event to the subscriber as shown below.

It
also adds the following tags to the sun-portlet.xml file.
-
|
<portlet>
<portlet-name>AccountBalance_A</portlet-name>
<events>
<consumes-event>transfer</consumes-event>
</events>
</portlet>
|
3.7
Generate Consume Event Source
Select
the consume_transfer event in the AccountBalance_A portlet in
storyboard and right click and choose the option “Generate
Consume Event Source”. This pops up a window where you can
specify the name for the method to be invoked when the event is
fired.
As
a result , the AccountBalance_A portlet imports the corresponding
packages and implements the PortletEventListener interface and
overrides the handleEvent() with the following code.
-
|
public void
handleEvent(EventRequest eventRequest, EventResponse eventResponse) {
if(eventRequest.getEventName().equals("transfer"))
{
handleConsumetransferEvent(eventRequest,eventResponse);
}
}
private void
handleConsumetransferEvent(EventRequest eventRequest, EventResponse
eventResponse) {
Object eventData =
eventRequest.getEventData();
if(eventData != null)
{
//Set EventData Object in portlet
session
eventRequest.getPortletSession(false).setAttribute("transfer",
eventData, PortletSession.PORTLET_SCOPE);
//uncomment this line if you want
to set the EventData as string in render parameter
//eventResponse.setRenderParameter("transfer",eventData.toString());
}
}
|
Now
update the method created with the following code:
-
|
private void
handleConsumetransferEvent(EventRequest eventRequest, EventResponse
eventResponse) {
Object eventData =
eventRequest.getEventData();
if(eventData != null)
{
double
amt=Double.parseDouble(eventData.toString());
if(amt < balance)
{
balance -=amt;
}
else
{
//TODO
}
}
}
|
Based
on the amount transferred (if its greater than balance) ,the
AccountBalance_A portlet can fire another event which will be consumed
by AccountBalance_B portlet.(This shows that event can also be
generated from a handleEvent())
In
order to fire a new event from AccountBalance_A portlet,Select
the AccountBalance_A portlet in the storyboard, right click and
choose “Add Event”and then rename the newly created event to
creditBalance.
Generate the source for the event. It will create the following code.
-
|
private void
generatecreditBalanceEvent(ActionRequest actionRequest, ActionResponse
actionResponse, String eventData) {
try{
PortletEventBroker peb = new
PortletEventBroker(actionRequest);
PortletEvent pe =
peb.createEvent("creditBalance");
pe.setEventData(eventData);
pe.fire();
} catch(Exception e) {
//TODO Catch Exception here
}
}
|
Note
** Change
the argument of the generatecreditBalanceEvent to (EventRequest
eventRequest, EventResponse eventResponse, String eventData)
Invoke
the generatecreditBalanceEvent() from handleConsumetransferEvent() to
fire the
new event.
-
|
if(amt < balance) {
balance -=amt;
generatecreditBalanceEvent(eventRequest,eventResponse,eventData.toString());
}
|
Next
step is to consume this event in the AccountBalance_B portlet. Drag the
creditBalance Event into the AccountBalance_B portlet and generate
consume event source . Update the source created with the following
code.
-
|
private void
handleConsumecreditBalanceEvent(EventRequest eventRequest,
EventResponse eventResponse) {
Object eventData =
eventRequest.getEventData();
if(eventData != null)
{
balance+=Double.parseDouble(eventData.toString());
}
}
|
Finally
clean ,build and deploy the portlet on the PortletServer. On accessing
the portlets, you will find all the three portlets displayed
as follows.

Enter
an amount in Fund Transfer portlet and click transfer. You will find
that the AccountBalance_A is reduced by the transfer amount and
AccountBalance_B be increased by the same amount.
4
Example Source Code
Click
here
to
get the source code of the example.
5
References
Portlet
Creation Made Easy – Part 1