Monday, March 28, 2016

Liferay 7 Features

Liferay 7 is exciting release from Liferay Inc. and it’s definitely a promising product, will have many new functional features and many architectural improvements.

Liferay is really putting lot of efforts towards to Liferay 7 development. Liferay 7 Expedition is program there we can see all new features and updates about Liferay 7.

Liferay completed alpha and beta releases and they already released the Liferay 7 RC version. Couple of months they are going to release Liferay 7 GA release and no doubt it’s really a promising product for developers and customers as well.


The following are the Liferay 7 features

OSGi Support
Bootstrap 3.0 Look and Feel
Java 8 Support
Alloy Editor
Elastic Search
Support Integration Testing through Arquillian
Application Display Templates Support for Login, Language and Breadcrumb portlets.
Improvements in Web content management
Singe Page Application Development
Document Management storages extracted as modules      
Service Builder code now uses Declarative Services instead of Spring for dependency injection

OSGi Support

Liferay 7 has supported OSGi modular based environment. Open Services Gateway initiative is standards for modular based application development.

OSGi will provide ability to create application in several components and all components together work as application and each component is independent and much decoupled from other components of course sometimes there is dependency among components.

OSGi provide container and it will responsible of components lifecycle so that we won’t need to concentrated on underlying things about component such as components lifecycle and its dependency related things.

OSGi will get rid of you from class loader issues and as for OSGi several components together became as bundle and each bundle have its own class loader. All bundles class loaders will be managed by OSGi container so that we cannot get any class loader issued and especially you can get rid of from ClassNotFoundException and NoClassDefFoundError

OSGi is dynamic modular development architecture so that we can deploy and un-deploy bundles without down the application. Another advantage is same time we can run different versions for same application such way OSGi container developed.

Traditional web application have Application server and we deploy application into application servers when we move application to another environment such as from UAT to production we need to take care many configurations and other related things.

OSGi have different way of implementation to provide web application runtime support so that each thing we can consider as service. To run web application in OSGi we need to integrate or deploy HTTP service so that we can run web applications.

Liferay 7 has implemented these OSGi support so that we can develop Liferay application as bundles or components. Running these bundles or deploy and un-deploy definitely going to be very easy when compared with before architecture.

We don’t worry about portlet, hook, Ext, theme and layout and everything going to be bundle. These bundles we can activate, run, and deactivate and we don’t need to down the application.

Liferay 7 has introduced new way of Liferay application development that is bundles. We cannot differentiate development for portlet, hook, Ext, theme and layout. We can forget about Liferay Plugins SDK environment and we can start developing Liferay Applications as OSGi bundles.

Liferay is developing application development environment and its tool called BLADE Tools which will provide way to develop Liferay Applications as OSGi bundles.
BLADE tools offer you MAVEN and GRADLE based build to create and deploy Liferay Applications as OSGi bundles.

BLADE Tools for Liferay


Liferay also started developing Liferay IDE and its used BLADE Tools to create and deploy bundles. Now it’s in progress and for now we can directly use BLADE Tools Command Line Interface to create Liferay Applications as OSGi bundles.


Liferay 7 supports to use Service builder tool in OSGi bundles, it’s also provide way to call Liferay API inside OSGi bundles and its provide support to use JSP in OSGi bundlels.
Liferay 7 have used features from Apache Felix and Eclipse Equinox OSGi implementation. It provide OSGi console (Apache GOGO) and Command Line Interface to deploy, activate and de-activate bundles in OSGi container.


Bootstrap 3.0 Look and Feel

Liferay 6.2 have used Bootstrap 2.x and Now Liferay 7 have used Bootstrap 3.0 so that look and feel for portal and its applications are really going to be good. All Liferay AUI components have used Bootstrap 2.x before and using Bootstrap 3.0 in Liferay 6.2 is really challenging and once we use bootstrap 3.0 UI developer need to put lot effort to adjust the things in theme level or AUI components level.

Now with bootstrap 3.0 all Liferay AUI components already used it and it won’t be problem to create themes with bootstrap 3.0.


Java 8 Support

Liferay 8 completely computable with Java 8. Oracle have stopped updates for Java 7 and Java 6. So now Liferay 7 completely considered only Java 8 and they implemented Liferay 7 to run on Java 8.

Java 8 have many features so it will be valued added to Liferay Application development like Lambdas and Functional Interfaces, Default and Static Methods in interfaces ,Stream API .Date Time API Improvements for Time Zones and Nashorn, JavaScript Engine are really pretty cool features in Java 8. We cannot see java.lang.OutOfMemoryError: PermGen space in Liferay 7 any more.


Alloy Editor

Alloy Editor is one of project from Liferay and it has provided better way of edit and create web content in Liferay. Liferay previous versions have used CKEditor and Now Liferay 7 have used Alloy Editor.

Alloy Editor Build on top CKEditor and its provided better and good look feel option to edit or create content. This editor we use extensively for WCM, Blogs, Wikis and Message boards in Liferay and also we can use it for custom portlets.

Nice feature is that it provides inline content edit so that edit control will available for each elements in content like text, images, headers and links. So that we can directly click on elements can see the edit control.


Elastic Search

Liferay before it’s used the Lucene search engine to search content in Liferay and Liferay 7 integrated Elastic Search as default search.


Support Integration Testing through Arquillian

One of the challenging thing Liferay is testing of application and there is no specific way to test and run test cases in Liferay. Generally we use Junit for unit testing.
Liferay have come up with better testing support to test and execute Liferay applications and Liferay 7 have given flexibility to use integration testing for portlets and OSGi plugins using Arquillian integration framework. This really cool for test Liferay applications such as OSGi bundles and portlet.


Application Display Templates Support for Login, Language and Breadcrumb portlets.

ADT is great way of customize the look and feel of existed portlets in Liferay through Free Marker Templates. In Liferay 6.2 have given ADT support for few portlets such as Asset Publisher, Blogs, Wikis, Navigation and Category Navigation  and it added few more portlet in the list such as Login, Language and Breadcrumb portlets.


Improvements in Web content management

Liferay 7 brings some of cool improvements in Web content management system such as Alloy UI editor to create and edit web content and ability to create mail templates for multiple languages and its changed CKFile browser to Liferay own file browser in side Alloy Editor.

Singe Page Application (SPA) Development

Now trends is Single Page Application using MVC based java script libraries with awesome look and feel with bootstrap. Liferay 7 have bring support for SPA application using SennaJs. Now all portlet become as Single Page Application so that user can navigate to anywhere without reloading entire portal page.


Document Management storages extracted as modules

Previous Liferay version have different ways of documents storage systems such as Jackrabbit (JCR) , DB Store and Advanced Filesystem when we want switch among these stores we need to do configuration in portal properties files and to effect the changes we need to stop server and start it.

Now Liferay 7 have introduced these features as OSGi modules so that we can dynamically active or deactivate bundles so that we can easily switch among these storage systems.
Liferay 7 have introduced following types of document storage as bundles such as Advanced Filesystem, CMIS, DB, Filesystem, JCR and S3.

Service Builder code now uses Declarative Services instead of Spring for dependency injection

Declarative Services is one of run time service provided by OSGi container to specify dependency services to other components and it make available these services to consumer bundle/component.

These dependency services declared as XML configuration so that when we deploy bundle into OSGi container then its resolves the all the dependency services otherwise bundle won’t be activate and its responsibility taken care by Service Component Runtime, we can use either Equinox Declarative Service or Apache Felix SCR to provide feature in OSGi container. Liferay 7 have used default OSGi Declarative Service model than Spring dependency. Generally Declarative Service model service will be available or activates when it started using otherwise it won’t be start but Spring Decency, the spring container will prepare the object based on XML configuration it will inject all objects and make it available complex Object in the spring container even we use it or not.

Due to Declarative Service we can resolve all dependency services resolution before bundle activated so that there is no run time exceptions or errors with respect dependency services.

Challenges

Liferay 7 is really good exciting but migration from older Liferay version to Liferay 7 is really challenging task because changes made at articular level.

One good thing is that Liferay 7 still used the traditional application server to run Liferay core portal than completely switching to OSGi HTTP based service. This really sign that we can migrate older versions to Liferay 7.

Due to Liferay 7 still used the Traditional application server so that we have more possibility to deploy all Liferay applications which are developed for previous versions will work and run in Liferay 7

Of course Liferay 7 already focused on conversion process from old Liferay plugins to OSGi based bundles.

Developer really need to habituate to OSGi based bundles development for Liferay 7 so its take some time for developer to understand development process. Because several years developers habituated to Liferay Plugins SDK and different types Liferay application like hooks, portlet, theme, layout and Ext and next we need to look at in the context that everything is OSGi bundle.

Sources:



Author

Introduction to JSR 362 / Portlet Specification 3.0

Generally any portal implementation must be based on JSR 168 and JSR 286 standards and all portal must have implemented these specification to being as portlet technology based portal.

JSR 286 was finalized in 2008 and it was last specification was released for portlet technology and over the years Java Community Process group have introduced new specification that is JSR 362.

In each specification new features was introduced and those were implemented in the portals. Same way JSR 362 added few more new specification and improvements to the portals.

                                
JSR 362 / Portlet 3.0

JSR 362 have added new features and improvements for portlet implementation. All JSR 286 specification already covered in JSR 362 besides it added few more new specifications and improvements

The following are the specifications

Support JEE 7 features in Portlets
Resources sharing among portlets
Better client side support
Improved the mobile devices support
Optimise Java Server Faces (JSF) support
Support for WSRP future specification
Web Socket Support
Support Open Social Standards
Improvements in Portlet Event based Communication

Support JEE 7 features in Portlets

JEE 7 come up with many new features in each JSR specification. JSR 362 will covered the JEE 7 features.
Following is link will show you all features added in JEE 7


Resources sharing between portlets

Generally in portlet communication we can exchange data among the portlets not resources such as files, documents and images. JSR 362 implemented resource sharing between portlets such a way we can share resources between portlets.

To know more about what JSR 286 covered you can have look at Inter Portlet Communication.


Improved the mobile devices support

Portal and portlet technology major challenge is User Interface and its support to different device types. Generally portal page composition of multiple portlet so User Interface is big challenge.

JSR 362 have brought some of improvements to support mobile clients so that portal look and feel will be good in mobile devices too.

Better client side support

As we discussed User Interface is major challenge in portlet technology so new specification bring some of new feature to improve client support. It’s like bootstrap support and html5 support.

Optimise Java Server Faces (JSF) support

Generally to work web framework in portals then web framework vendors need to provide portlet bridges so that web application lifecycle will be transformed to portlet lifecycle.

But as for specification portlet technology default support for Java Server Faces in the past specification and some of the things was improved in the new specification. So that we can easily use JSF framework based portlets in portals.

Liferay already have implemented and have given support to develop JSF based portlets and run into Liferay Portal. Now Liferay considered JSR 362 and they stared implementing these features in Liferay JSF implementation.



Support for WSRP future specification

Web Services for Remote Portlets (WSRP) is standers to share portlet with other portal platforms. Its presentation oriented web service so that we can directly display portlets in other portal platforms.

Assume if we have some portlet running in Liferay portal and other portlet in WebSphere portal. If we want to share Liferay portlets with WebSphere or WebSphere portlets with Liferay then WSRP will help you to share portlets among different portals rather than re-implements the same portlets in other platforms.

Generally through web services we can only share data among different platforms not presentation or user interface but WSRP will also share presentation along with data so that we don’t need to develop any presentation.

JSR 168 have supported WSRP 1.0 specification and JSR 286 have supported WSRP 2.0 specification. Now JSR 362 is supporting WSRP 3.0 specification.


Web Socket Support

Web Socket is protocol and it allows communication between client and servers with single TCP connection. Its possible to establish a continuous full-duplex connection stream between a client and a server. This will help in streaming and also if something updated in server it will automatically push to the client. JSR 362 will support this kind of communication and really its big asset to the portals and its portlets.

Example:


Support Open Social Standards

Open Social is strands which will give us to created web applications using HTML, CSS and Java Script. It’s easy to create dynamic application using open social standards and its consumed REST bases web services to create dynamic web application. We can easily build some widgets or portlet using these standards.

Liferay already have introduced in Liferay 6.2 release to created Open Social Widgets in Liferay portal.


Improvements in Portlet Event based Communication

Portlet communication can happened in different ways and one of the communication model is Event based. JSR 362 have improved some of the things in Event based communications.

Sources:

https://www.jcp.org/en/jsr/detail?id=362    


Author
        

Wednesday, February 24, 2016

Modify / Add Request parameter values in Liferay

Generally request parameter values are immutable once the request process is started. Some time we may get some requirement that force you to add or modify the request parameter values. Assume scenario once we submit the form to the controller we would like to modify or add the parameter values before it reach the controller.

Http Servlet Request Wrapper is the way to modify the request parameter values. We will use Http Servlet Request Wrapper with servlet filter combination so that we can modify or add new parameter values.

Example Scenario

Assume the example scenario that when user login into the Liferay portal before it reach struts controller we would like to change the redirect parameter value.

Note:

This just scenario I chosen to explain the concept.
We will use Http Servlet Request Wrapper with servlet filter combination to achieve this concept. In Liferay we will use Hook plugin to implement the concept.

In Liferay login mechanism when user submit the user name and password then it will submitted to /login/login struts controller path. Before it reach struts controller (LoginAction.java) we would like to change the redirect parameter value in the filter using Http Servlet Request Wrapper concept.

Steps to Implementation
  1. Create Liferay Hook
  2. Create Custom Http Servlet Request Wrapper
  3. Create Servlet Filter Class and modify the request parameter values
  4. Configure Servlet Filter in liferay-hook.xml
  5. Configure Struts path in liferay-hook.xml
  6. Create Struts Action Hook for Login Action and observe the modified parameter value

Create Liferay Hook

Creating hook using Liferay IDE is very straight forward way and its easy. Follow below articles to create Liferay hook plugin.


Create Custom Http Servlet Request Wrapper

We need to create custom Http Servlet Request Wrapper and the following is custom Http Servlet Request Wrapper. This class is responsible for modify or add request parameters.


package com.liferaysavvy.requestwrapper;

import java.util.Collections;
import java.util.Enumeration;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;

public class AddModifyRequestParamValueWrappedRequest extends HttpServletRequestWrapper
{
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;

/**
* Create a new request wrapper that will merge additional parameters into
* the request object without prematurely reading parameters from the
* original request.
*
* @param request
* @param additionalParams
*/
public AddModifyRequestParamValueWrappedRequest(final HttpServletRequest request,
final Map<String, String[]> additionalParams)
{
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
}

@Override
public String getParameter(final String name)
{

String[] strings = getParameterMap().get(name);
if (strings != null)
{
return strings[0];

}

return super.getParameter(name);
}

@Override
public Map<String, String[]> getParameterMap()
{
if (allParameters == null)
{
allParameters = new TreeMap<String, String[]>();
allParameters.putAll(super.getParameterMap());
allParameters.putAll(modifiableParameters);
}
//Return an unmodifiable collection because we need to uphold the interface contract.
return Collections.unmodifiableMap(allParameters);
}

@Override
public Enumeration<String> getParameterNames()
{
return Collections.enumeration(getParameterMap().keySet());
}

@Override
public String[] getParameterValues(final String name)
{
return getParameterMap().get(name);
}
}


Create Servlet Filter Class and modify the request parameters

Now we will implement servlet filter and we will Custom Servlet Request Wrapper to modify parameter values or we can also add new parameters. Once request parameters are modifies then we will give this object to doFilter(--) method to do subsequent process.


package com.liferaysavvy.requestwrapper;

import java.io.IOException;
import java.util.Map;
import java.util.TreeMap;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ParamUtil;

public class ChangeRequestParamFilter implements Filter {

@Override
public void destroy() {
logger.info("ChangeRequestParamFilter");
}

@Override
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {

logger.info("inside ChangeRequestParamFilter doFilter ");
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;

/*Getting actual Redirect Param Value*/
String actuallRedirectValue = ParamUtil.getString(httpServletRequest,"redirect");
logger.info("Actual Redirect Param Value:" + actuallRedirectValue);

/* Modifying redirect param value and also adding new parameter to request object*/
Map<String, String[]> modifyAddParamValueMap = new TreeMap<String, String[]>();
String[] redirectParamArray = new String[1];
redirectParamArray[0] = "http://localhost:8080/web/guest/custom-portlet-workflow";
modifyAddParamValueMap.put("redirect", redirectParamArray);
modifyAddParamValueMap.put("newParam",new String[]{"Hello I am New Param value"});
HttpServletRequest wrappedRequest = new AddModifyRequestParamValueWrappedRequest(
httpServletRequest, modifyAddParamValueMap);
filterChain.doFilter(wrappedRequest, servletResponse);
}

@Override
public void init(FilterConfig filterConfig) {

logger.debug("Called ChangeRequestParamFilter init(" + filterConfig + ")");
}

private static final Log logger = LogFactoryUtil
.getLog(ChangeRequestParamFilter.class);

}


Configure Servlet Filter in liferay-hook.xml

Use following configuration in liferay-hook.xml file


<servlet-filter>
<servlet-filter-name>ChangeRequestParamFilter</servlet-filter-name>
<servlet-filter-impl>com.liferaysavvy.requestwrapper.ChangeRequestParamFilter</servlet-filter-impl>
<init-param>
<param-name>hello</param-name>
<param-value>world</param-value>
</init-param>
</servlet-filter>
<servlet-filter-mapping>
<servlet-filter-name>ChangeRequestParamFilter</servlet-filter-name>
<url-pattern>/web/guest/home/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
</servlet-filter-mapping>


Note:

From the above configuration Filter will be execute when we request server with /web/guest/home/* path.

Configure Struts path in liferay-hook.xml

We are going to see resulted values in Custom Login Action struts action for /login/login path so we need to configure the path in liferay-portlet.xml file.


<struts-action>
<struts-action-path>/login/login</struts-action-path>
<struts-action-impl>com.liferaysavvy.requestwrapper.CustomLoginStrutsPortletAction</struts-action-impl>
</struts-action>


Create Struts Action Hook for Login Action and observe the modified parameter value

Finally we will see the modified or newly added parameter values in Custom Login Action Struts action class.


package com.liferaysavvy.requestwrapper;

import javax.portlet.ActionRequest;
import javax.portlet.ActionResponse;
import javax.portlet.PortletConfig;
import javax.portlet.RenderRequest;
import javax.portlet.RenderResponse;
import javax.portlet.ResourceRequest;
import javax.portlet.ResourceResponse;
import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.struts.BaseStrutsPortletAction;
import com.liferay.portal.kernel.struts.StrutsPortletAction;
import com.liferay.portal.kernel.util.ParamUtil;
import com.liferay.portal.util.PortalUtil;

public class CustomLoginStrutsPortletAction extends BaseStrutsPortletAction {

@Override
public void processAction(StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, ActionRequest actionRequest,
ActionResponse actionResponse) throws Exception {
ServletRequest servletRequest = PortalUtil.getOriginalServletRequest(PortalUtil.getHttpServletRequest(actionRequest));
String modifiedRedirectValue = servletRequest.getParameter("redirect");
String newParamValue = servletRequest.getParameter("newParam");
logger.info("Modified Redirect Value:"+modifiedRedirectValue);
logger.info("Nee Parameter Value:"+newParamValue);
originalStrutsPortletAction.processAction(portletConfig, actionRequest,
actionResponse);
}

@Override
public String render(StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, RenderRequest renderRequest,
RenderResponse renderResponse) throws Exception {
return originalStrutsPortletAction.render(portletConfig, renderRequest,
renderResponse);
}

@Override
public void serveResource(StrutsPortletAction originalStrutsPortletAction,
PortletConfig portletConfig, ResourceRequest resourceRequest,
ResourceResponse resourceResponse) throws Exception {

originalStrutsPortletAction.serveResource(portletConfig,
resourceRequest, resourceResponse);
}


private static Log logger = LogFactoryUtil
.getLog(CustomLoginStrutsPortletAction.class);
}


Observation

Deploy hook into Liferay portal server

Drag and Drop Liferay sign in portlet in home page

Site page URL should be as follows http://localhost:8080/web/guest/home

The following screen shows home page with sign in portlet



I have used /web/guest/home is filter path that is why Sign In portlet should be placed into home page so that filter will be executed when you login into portal.

Once you have done sign in process in Liferay portal then filter gets called and we can see redirect param value is empty later Custom Login Action will be executed there you can see redirect value that is modified in the filter. These are all will be printed in the server console.

This how we can observed modified parameter values in Login Action class.

Server Console


20:52:30,377 INFO  [http-bio-8080-exec-159][ChangeRequestParamFilter:31] inside ChangeRequestParamFilter doFilter
20:52:30,378 INFO  [http-bio-8080-exec-159][ChangeRequestParamFilter:36] Actual Redirect Param Value:
20:52:30,396 INFO  [http-bio-8080-exec-159][CustomLoginStrutsPortletAction:29] Modified Redirect Value: http://localhost:8080/web/guest/custom-portlet-workflow
20:52:30,396 INFO  [http-bio-8080-exec-159][CustomLoginStrutsPortletAction:30] New Parameter Value: Hello I am New Param value


Server Console




Note:

I just showed this example to understand how to modify or add new parameters in request object. This may or may not be the real time scenario but we can understand the concept from the example.


Author

Popular Posts

Recent Posts

Recent Posts Widget