Pages

Friday, 21 June 2013

What is Inter Portlet Communication in JSR 286 Portlets?

Inter Portlet Communication

Portlet  to  Portlet  Communication
Introduction
The first version of the portlet specification, JSR-168/portlet1.0, did not include any support for Inter Portlet Communication. The second version, JSR-286/ portlet2.0, which is supported for IPC  Mechanism.
IPC  is made easy  with JSR-286 to share the data between two portlets. Using IPC mechanisms, we can share the data from ACTION to VIEW phase and  VIEW-VIEWPhase.
There are 3  ways  to  share  the  data   between  2  portlets.
1.      Portlet session
2.      IPC  Mechanisms
2.1             Public Render Parameters
2.2             Event
2.3             Client-Side IPC
3.      Cookies

1.      1. Portlet  Session

By default , Each war has its own session and will not be shared with other  wars. Liferay provides a mechanism by which Portlets can share session attributes across WARs.

A PortletSession is created for each user per portlet application. This makes the PortletSession useful for communicating all user related information among different portlets in the same portal application.


Step 1:  set below attributes in Portlet1


liferay-portlet.xml :

<portlet>
<private-session-attributes>false</private-session-attributes>
</portlet>

     Step 2:  To set the Session:

PortletSession session = renderRequest.getPortletSession();
session.setAttribute("sessionValue",some-value , PortletSession.APPLICATION_SCOPE);

Step 3 : Get the Session Value in Portlet2


PortletSession ps = renderRequest.getPortletSession();
String tabNames = (String)ps.getAttribute("sessionValue ",ps.APPLICATION_SCOPE);


2.      IPC Mechanism

2.1 Public Render Parameter :   IPC ( Inter Portlet Communication)  : 

In JSR 168, the render parameters set in processAction is only available in the render of the same portlet. With the Public Render Parameters feature, the render parameters set in the processAction of one portlet will be available in render of other portlets also.
By adding the following property in portlet-ext, we can enable portlets to share render states with other portlets that are on different pages:
portlet.public.render.parameter.distribution=ALL_PORTLETS
Step 1:  Add below attribute in “Sender-Portlet”
           
            <portlet-app>
<portlet>
            <supported-public-render-parameter>
 id1
</supported-public-render-parameter>
</portlet>

<public-render-parameter>
  <identifier>id1</identifier>
<qname xmlns:x="http://abc.com/userId">x:param1</qname>
</public-render-parameter>
</portlet-app>

Note: We  can declare a list of public paramters for a portlet application.


Step  2:

 We can set render parameter in the processAction() method by using the defined public render parameter identifier as the key.

response.setRenderParameter("id1", “someIdValue”);

e.g.

public void processAction(ActionRequest  request, ActionResponse response)

throws IOException, PortletException  { ........
response.setRenderParameter("id1", “someIdValue”); ........

}


Step  3 : Receiver Portlet Portlet  “portlet.xml”

Specify the render parameter the portlet would like to share in the portlet section.

<portlet-app>
< portlet >
< portlet-name >PortletB< /portlet-name >
< supported-public-render-parameter >id1< /supported-public-render-parameter >
< /portlet >
<public-render-parameter>
  <identifier>id1</identifier>
<qname xmlns:x="http://abc.com/userId">x:param1</qname>
</public-render-parameter>
</portlet-app>



Step 4 :

A portlet can read public render parameter using following method
request.getPublicParameterMap()

Note: Public render parameters are merged with regular parameters so can also be read using

request.getParameter(“id1”);
           
Step 5:

A portlet can remove a public render parameter by invoking following methods.

response.removePublicRenderParameter(“id1”)


3         Event  :   IPC ( Inter Portlet Communication)  :


 

 
Portlet events that a portlet can receive and send.
In JSR-168 :
The only way to achive eventing was through portlet session.
Limitation : Portlet has to be in the same web application.

In JSR-286 :
JSR 286 (Portlet 2.0) defines a lifecycle for events, so that eventing is possible between portlets that are in different web applications.
By adding the following property in portal-ext, we can enable portlets to send and receive events from other portlets that are on different pages
            portlet.event.distribution=ALL_PORTLETS
Step 1: Sender Portlet
portlet.xml
-----------
The portlet standard defines a way of telling the portlet container  which portlet is responsible for sending an event.

Add this inside <portlet> tag:

         <portlet-app>

<portlet>
                        <supported-publishing-event xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
</supported-publishing-event>

             </portlet>

<event-definition xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
<value-type>java.lang.String</value-type>
</event-definition>
         </portlet-app>

Step 3 : Set the event in process action:


 javax.xml.namespace.QName qName =
new QName("http://liferay.com", "empinfo", "x");
response.setEvent(
qName,
"Hai You have received Event Data sent from Sender Portlet");


Step 4: Listner Portlet

portlet.xml:
-----------

<portlet-app>
<portlet>
<supported-processing-event xmlns:x='http://liferay.com'>
                                    <qname>x:empinfo</qname>
                        </supported-processing-event>
</portlet>
<event-definition xmlns:x='http://liferay.com'>
<qname>x:empinfo</qname>
            <value-type>java.lang.String</value-type>
</event-definition>
</portlet-app>

Step 5: get the EVENT:

This Even will be called after processAction as shown in the picture:

Lifecycle for IPC Event:
              

@javax.portlet.ProcessEvent(qname = "{http://liferay.com}empinfo")
 public void handleProcessempinfoEvent(
javax.portlet.EventRequest request, javax.portlet.EventResponse response)
throws javax.portlet.PortletException, java.io.IOException {           
        javax.portlet.Event event = request.getEvent();
        String value = (String) event.getValue();
      
            System.out.print("value in process event>>>>>>>>>" + value);
            response.setRenderParameter("empInfo", value);
 }


2.3 Client-Side IPC  : 

There are 2 APIs for client side IPC.

Event generation (call from portlet A):

Liferay.fire('<eventName>', {
            name : value 
});


e.g.
Liferay.fire('planTravel', {
            origin : 'pune',
            destination : 'mumbai'
        });

Event Listener ((call from portlet B):

Liferay.on('<eventName>', function(event) {
       
    });


e.g.
Liferay.on('planTravel', function(event) {
        showNews('', event.origin);
        showNews('', event.destination);
    });


3.  Cookies

Other than the IPC mechanism,  There is an easiest way to get the data between portlets on different pages called COOKIES.  
But there are some limitations for cookies  that it will not accept more than 4KB size datas and the biggest limitation is, the 20 cookies per server limit, and so it is not a good idea to use a different cookie for each variable that has to be saved


Portlet 1    :

To Set the Cookies through jQuery :

<script src="/html/js/jquery/cookie.js" type="text/javascript" > </script>
function setCookie(docURL) {
jQuery.cookie("cookieParam",docURL);
}
To Set the Cookies through java / jsp:

HttpServletResponse response = PortalUtil.getHttpServletResponse(
                                    actionResponse);
Cookie cookieParam = new Cookie("cookieParam ", password);
response.addCookie(cookieParam);

Portlet 2:

To get the Cookies through jQuery :

jQuery.cookie("cookieParam ");

To get the Cookie through java/ jsp :

String sessionid = "";
Cookie[] cookies = request.getCookies();
    if (cookies != null) {
      for (int i = 0; i < cookies.length; i++) {
        if (cookies[i].getName().equals("cookieParam ")) {
          sessionid = cookies[i].getValue();
          break;
        }
      }
    }


Friday, 14 June 2013

Elements of Portal Page




  •   A portlet generates markup fragments.
  •  A portal may add a title, control buttons and other decorations to the markup fragment generated by the portlet, this new fragment is called a portlet window.
  •   Then the portal may aggregate portlet windows into a complete document, the portal page.
Reference Link: 

What is Portlet Container??

Portlet Container

1).The lifecycle of a portlet is managed by the portlet container. A portlet container runs portlets and provides them with the required runtime environment. A portlet container contains portlets and manages their lifecycle. It also provides persistent storage for portlet preferences. A portlet container receives requests from the portal to execute requests on the portlets hosted by it.

2).A portlet container is not responsible for aggregating the content  produced by the portlets. It is the responsibility of the portal to handle the aggregation

3).A portal and a portlet container can be built together as a single component of an application suite or as two separate components of a portal application.

4).The portlet container is an extension of the servlet container. As such, a portlet container can be built on top of an existing servlet container or it may implement all the functionality of a servlet container. Regardless of how a portlet container is implemented, its runtime environment is assumed to support at least Servlet Specification 2.4.

Reference Link:

Thursday, 13 June 2013

What is Portlet Preferences in Liferay???

Portlet Preferences

There are two kinds of portlet preferences available. 
  • Static Preferences
  • RunTime Preferences
  •   
1. Static Preferences:

It is nothing but, the portlet prefrences which we set will be constant troughout the portlet.
Example: 
Mention the following lines inside your portlet.xml file:
<portlet-preferences> 
 <preference>
      <name>department</name>
      <value>liferay</value>
   </preference>

    <preference>        <name>company</name>
      <value>cignex</value>
   </preference>
</portlet-preferences>

Access the above preferences department and company in your jsp or java files.
PortletPreferences preferences = renderRequest.getPreferences();
String department = preferences.getValue("departmentt", "");
String company = preferences.getValue("company", "");

2. RunTime Preferences:

We can change the portlet preferences value at runtime and we can access the value throught the portlet. The preferences for a portlet are stored in "PortletPreferences" table.
Steps to follow:

  • Access the "department" value in jsp page from the portlet preferences table.
  • Provide another jsp page to modify the department value.
  • Update the department value in portlet preferences table.
Example:

Step 1: Mention the following code where you want to access department value. In our case we using view.jsp page.

<%
PortletPreferences preferences = renderRequest.getPreferences();
String portletResource = ParamUtil.getString(request, "portletResource");
if (Validator.isNotNull(portletResource)) {
   preferences = PortletPreferencesFactoryUtil.getPortletSetup(request, portletResource);
}
 String department = preferences.getValue("department", "liferay");
%>
Note: If the department value is null while fetching from portlet preferences table, by default liferay will be assigned to department value, because we mentioned liferay will be the default value for department.
Step 2: Mention the following code where you want to provide the UI for altering the department value. In our case we using modifyportletprefernces.jsp page.

<%
PortletPreferences preferences = renderRequest.getPreferences();
String portletResource = ParamUtil.getString(request, "portletResource");
if (Validator.isNotNull(portletResource)) {
  preferences = PortletPreferencesFactoryUtil.getPortletSetup(request, portletResource);
}
String department = preferences.getValue("department", "liferay");
%>
<form action="Mention your action" method="POST" name="<portlet:namespace />fm">
  <table>
    <tr>
      <td class="lfr-label">Page Title</td>
      <td><input name="<portlet:namespace />department" type="text" value="<%= department%>"/></td>
    </tr>
  </table>
  <input type="submit" value="<liferay-ui:message key="save" />" />
</form>
Step 3: Mention the following code in your action class to update the department value in the portlet preferences table.

String depratment= ParamUtil.getString(actionRequest, "department"); 
//Getting the PortletResource
String portletResource = ParamUtil.getString(actionRequest, "portletResource"); 
//Creating the Reference for Portletpreferences Table
PortletPreferences prefs = PortletPreferencesFactoryUtil.getPortletSetup(actionRequest, portletResource);
 //Setting The Value in the PortletPreferences table
prefs.setValue("department", department);
prefs.store();

Don't miss it:
Reference Link:
http://www.liferaysolution.com/2011/02/portlet-preferences.html#.Ubq9CPml7-s