Pages

Thursday, 27 June 2013

What is View and Edit Mode in Liferay Portlet?

View mode is what is displayed a user logs in to the liferay portal and various portlets are displayed to him.

Edit mode is the configuration options that are displayed when the edit button is clicked on the portlet.

Difference between Liferay Hook and Ext plugins

Hook:
Hooks is a feature to catch hold of the properties and JSP files into an instance of the portal as if catching them with a hook. Hook plugins are more powerful plugins that come to complement portlets, themes, layout templates, and web modules. A hook plugin is always combined with a portlet plugin. For instance, the portlet social-portlet is a portlet plugin for Social Office with hooks. In general, hooks would be very helpful tools to customize the portal without touching the code part of the portal. In addition, you would use hooks to provide patches for the portal systems or social office products.
source:Liferay Portal 6 Enterprise Intranets
EXT:
EXT is used to customize and extend the Liferay portal. EXT builds a new ROOT webapp and replaces by a huge build mechanism your existing Liferay portal.
The Liferay EXT Environment is where you would ideally make changes to the portal itself. In other words, this is where you customize or “extend” the portal. You may ask, “Why can’t we just make the changes to the portal source directly?” The answer is that you technically CAN, but if and when you have to upgrade, you will have a tough time sorting out what is out-of-the-box and what is customized. EXT Environment keeps things separate.



Hooks Plugins
Ext Plugins

Hook Plugins are used to customize or override the default behavior of liferay in the form of properties and jsp files.

Ext Plugins are used to customize and extend the Liferay Portal.i.e almost customize everything.
Nothing but we can create new Root Web app.
Using Hooks we can override
a).Event Handlers(Application startup events,Login events,Service Events).
b).Language Bundles.
c).Jsp files(either portal or portlet folder).
d).Model Listners.
e).Services.
Using Exts we can customize
a).portal-impl as ext-portal-impl.
b).portal-service as ext-portal-service.
c).util-bridges as ext-portal-utilbridges..
d).util-java as ext-util-java.
e).util-taglib as ext-taglib.
f).web as ext-portal-web.

These are recommended way of extension and maintaince easy.

These are recommended when there is no way of implementing required functionality  using hooks.

Hot deployable

Not hot deployable and server must restart

Combine with other plugins like portlets.

These are some difficulty and customize almost everything.



What is the flow of http request in Liferay

Flow of Request in Liferay:-


Browser » App Server (eg Tomcat) » Liferay(Main Servlet) » layout (Database Table of Liferay) 

>>Creates and construsts Theme display object » Page Layout » Portlets » portlet.vm » portal_normal.vm » HTML


1).When a url is request by browser, the application server (Tomcat or any other server running Liferay) handles the request and forwards it to Liferay(MainServlet in portal.jar). and then creates and construts themedisplay object which contain all the various configuration parameters and values
2). From the request URL Liferay get the ‘page’ that is requested. This page is searched for the corresponding record in table ‘layout’ to check the page layout.
3). From page layout the portlets on pages is retrieved. The portlets are processed and out is placed in ‘portlet.vm’. This velocity file with parsed data is set in page layout to construct the whole page and output is then set to ‘portal_normal.vm’. 
4).Finally ‘portal_normal.vm’ is converted to HTML that is presented to the user.

For Breif Discussion in depth.

Many time we think like when we hit a url in browser what is the intermediate class by which request comes to our class. Below steps describes the flow of a browser request thru the Liferay code from request of the page, all the way down to rendering an individual portlet: 
  1. The initial request comes into the portal server from the browser, and hits the service() method of the class com.liferay.portal.servlet.MainServlet. Here, a variety of objects are created and added to the request for use by code downstream (such as company Id, user objects, etc.)
  2. Code passes through the servicePre() method of the class com.liferay.portal.events.ServicePreAction. Here is where the ThemeDisplay object is created and populated for downstream code use.
  3. The theme infrastucture code will call into the class com.liferay.taglib.util.ThemeUtil to render the content of a theme. It will call either the mehod includeJSP() to include JSP rendered content, or includeVM() to include Velocity rendered content.
  4. When using a Velocity based theme, the request will flow thru the class com.liferay.portal.velocity.VelocityVariables and the method insertVariables(). That method is where various Velocity variables for use by the theme system is added to the Velocity context.
  5. For each column in the page's layout, the PortletColumnLogic class processes each portlet using the processContent() method. In this method, the HTML that surrounds every portlet is generated. Further processing is then delegated to the RuntimePortletUtil via the processPortlet() method. Then on to the actual rendering...
  6. An individual portlet is rendered by the render_portlet.jsp code located (in Tomcat) in the webapps/ROOT/html/portal directory. This JSP is called to render each portlet on the page. Debug code can be added to this file to see exactly what is going on just before and just after the code in your custom portlet is executed.
  7. As will be found by looking through the JSP code, render_portlet.jsp uses InvokerPortletImpl's render() method to render portlets. The primary function of this method is to check if a portlet's expiration-cache has been set or has expired. If the expiration-cache has been set, InvokerPortletImpl then checks whether the portlet's most recently cached content is fresh enough to use.


Reference Link - See more at: http://www.opensourceforlife.com/2011/11/browser-request-thru-liferay-code.html#sthash.SJfqpfkZ.dpuf

Friday, 21 June 2013

What is the difference between application server and web server?


ApplicationServer: takes care of Security, Transaction, Multithreading, Resource pooling, load balancing, clustering, performence, highly availability, scalability, etc. Exposes business logic to client applications through various protocols, possibly including HTTP. Supports deployment of .war and .ear filesApplication server = webserver + EJB container.

Webserver: handles HTTP protocol. Receives HTTP request, it responds with an HTTP response.

What is a PortalSession Interface ?

Portet Session Interface.

User identification across many requests and transient information storage about the user is processed by PortletSession interace. One PortletSession is created per portlet application per client.
The PortletSession interface provides a way to identify a user across more than one request and to store transient information about that user.
The storing of information is defined in two scopes- APPLICATION_SCOPE and PORTLET_SCOPE.
APPLICATION_SCOPE: All the objects in the session are available to all portlets,servlets, JSPs of the same portlet application, by using APPLICATION_SCOPE.
PORTLET_SCOPE: All the objects in the session are available to the portlet during the requests for the same portlet window. The attributes persisted in the PORTLET_SCOPE are not protected from other web components.

What is a PortletContext Interface ?


The portlet view of the portlet container is defined by PortletContext. It allows the availability of resources to the portlet. Using this context, the portlet log can be accessed and URL references to resources can be obtained. There is always only one context per portlet application per JVM.

Difference Between JSR 168 and JSR 286 Portlets

Difference between JSR 168 and JSR 286

JSR 168 VS JSR 286

There are Major and Minor Improvements in  JSR 286 while compare with JST 168 

Major Improvements :- 

*. Events Handling – enabling a portlet to send and receive events and perform state changes or send further events as a result of processing an event.  
*. Public render parameters ( Shared Parameters) – allowing portlets to share parameters with other portlets.
*Resource serving (Resource Addressing) – provides the ability for a portlet to serve a resource
*. Portlet filter – allowing on -the -fly transformations of information in both the request to and the response from a portlet.

Minor Improvemetns :- 


  • getNamespace() – this method gives unique value for the portlet window
  • getWindowsID()- this method returns portlet window ID
  • Portlet Cookies- Can beset  on particular phase and retrieved on the subsequest phase
  • Additions to PortletRequestDispatcher
  • Portlet container runtime options

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.

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;
        }
      }
    }