Archive for December 2009
Liferay Session Sharing : Made Easy
- What I mean by ACTION-to-VIEW is on “action phase” of one portlet information is shared and made available to specific/all portlet’s “view phase”.
- There are use cases where we need a IPC mechanism to share information between portlets of different WARs in VIEW-to-VIEW .It means One portlet will share information from its VIEW phase and will be available to other Portlet in VIEW phase.
1.liferay-portlet.xml
<portlet>... <private-session-attributes>false</private-session-attributes> </portlet>
2. Use Namespace prefix to Share/Get shared session attribute:
portletSession.setAttribute( "LIFERAY_SHARED_mySpecialVar",value,PortletSession.APPLICATION_SCOPE);
portletSession.getAttribute( "LIFERAY_SHARED_mySpecialVar",PortletSession.APPLICATION_SCOPE);
How to Share with Servlet of Other WAR :-
portletSession.setAttribute( "LIFERAY_SHARED_mySpecialVar",value, PortletSession.APPLICATION_SCOPE);
Object value= portletSession.getAttribute ( "LIFERAY_SHARED_mySpecialVar",PortletSession.APPLICATION_SCOPE);//getting shared value portletSession.setAttribute ( "mySpecialVar",value,PortletSession.APPLICATION_SCOPE);//setting to 'local' session
request.getSession().getAttribute("mySpecialVar");
/***** <pre>* RUTVIJ SHAH MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. RUTVIJ SHAH SHALL NOT BE LIABLE FOR * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. * THIS SOFTWARE IS IN AS-IS FORM, YOU ARE FREE TO RE-DISTRIBUTE/CHANGE WITHOUT ANY NOTIFICATION TO AUTHOR. ******/ package myapp.liferayImpl.session.util; import com.liferay.portal.kernel.util.PropsUtil; import java.util.logging.Level; import java.util.logging.Logger; import javax.portlet.PortletRequest; import javax.portlet.PortletSession; /** * @author Rutvij Shah ( rutvij.shah@yahoo.com ) * LiferaySessionUtil provides helper methods to share your Session attributes * across WARs. * */ public class LiferaySessionUtil { /*** * This prefix is used by Liferay Portal to detect Session Attributes * for sharing betweeen WARs. */ private static final String LIFERAY_SHARED_SESSION_PREFIX=getSharedSessionPrefix(); private static final String LIFERAY_SHARED_SESSION_PREFIX_DEFAULT="LIFERAY_SHARED_"; /**** * It stores attribute as 'Shared' Attribute and will be available to other * portlets in different WARs. * * Attributes shared by this method will be available to only Portlets, * not other Web components i.e Servlet. * * @param key session Key to store value * @param value * @param request PortletRequest */ public static final void setGlobalSessionAttribute(String key,Object value,PortletRequest request){ if(key!=null){ String globalKey=getGlobalKey(key); PortletSession portletSession=request.getPortletSession(); portletSession.setAttribute(globalKey,value,PortletSession.APPLICATION_SCOPE); } } /**** * * It provides access to get shared session attributes from other portles * from diffrent WARs. * * @param key * @param request * @return */ public static final Object getGlobalSessionAttribute(String key,PortletRequest request){ Object value=null; if(key!=null){ String globalKey=getGlobalKey(key); PortletSession portletSession=request.getPortletSession(); value=portletSession.getAttribute(globalKey,PortletSession.APPLICATION_SCOPE); } return value; } /****** * * It provides a way to further share 'Shared'Session Attributes from * Portlet to other Web Components i.e Servlets . * * @param key * @param request */ public static final void shareGlobalSessionAttribute(String key,PortletRequest request){ if(key!=null){ Object value=getGlobalSessionAttribute(key, request); PortletSession portletSession=request.getPortletSession(); portletSession.setAttribute(key,value,PortletSession.APPLICATION_SCOPE); } } /*** * Helper method to generate Global key using Liferay shared prefix * @param key * @return */ private static final String getGlobalKey(String key){ return LIFERAY_SHARED_SESSION_PREFIX+key; } /******** * Helper method to get Liferay's Session Sharing prefix * Useful when Liferay is customized to use different prefix other than Default * * @return */ private static final String getSharedSessionPrefix(){ String value=null; try { /** * Getting value from portal.properties */ value = PropsUtil.get("session.shared.attributes"); } catch (Exception ex) { Logger.getLogger(LiferaySessionUtil.class.getName()).log(Level.SEVERE, null, ex); } if(value !=null){ if(value.contains(LIFERAY_SHARED_SESSION_PREFIX_DEFAULT)){ //if default prefix is configured use it value=LIFERAY_SHARED_SESSION_PREFIX_DEFAULT; }else{ //use first one from the list of prefix configured value=value.split(",")[0]; } }else{ /** * If none of the value configured use default one * Note: Session Sharing may not work as none of the value configured. */ value=LIFERAY_SHARED_SESSION_PREFIX_DEFAULT; } return value; } }
LiferaySessionUtil.setGlobalSessionAttribute ("mySpecialVar",value, portletRequest); //adding 'proper' prefix will be taken care by Utility
Object value= LiferaySessionUtil.getGlobalSessionAttribute ("mySpecialVar", portletRequest); //to get value for portlet LiferaySessionUtil.shareGlobalSessionAttribute ("mySpecialVar", portletRequest);//to share value to servlets
As you can see if Portlet Two only need to share it with servlet no need of first line.
request.getSession().getAttribute("mySpecialVar");
Feel free to share your comments on this. You can download LiferaySessionUtil.java from here : LiferaySessionUtil
User specific Preferences in Liferay
As per JSR 168 Specificaiton Portlet Preferences are user specific and may be shared across portlets/pages ( NOT Mandatory: config/edit_shared modes) which depends on portlet container.
If you have Websphere Portlet development experience you will wonder why preferences are not ‘user specific’ in liferay.
In this post I will explain how to solve this mystery and make your user specific preferences work in Liferay too.
Preferences in this example :
Portlet shows two preference values in VIEW mode JSP: A. Sets dynamically by API B. From portlet.xml.
Edit Mode shows and allow to update preferences.
processAction stores updated preferences.
Really simple use isn’t it ?
Expected Behavior:
When user Bob logs in to portal and set his preferences, he can see them in VIEW mode. So preferences are personalized only for Bob. When Alice/another user logs in to Portal she can set her preferences which is only for her, no other user can see.
In Websphere portal: As per Expected.
In Liferay portal: When Bob logs in and set his preferences and it will be set for Alice and David too .i.e when Alice logs in to portal she can see preferences values set by Bob. If she too updates, it overwrites value set by Bob.
I was wondering why its happening like this…because as per JSR if user sets Preferences in EDIT/VIEW/HELP mode it is user specific only.
Solution : Liferay supports great level of customization for preferences (I will explain it in details in my future posts).
But by default Liferay sets some customized levels for preferences ‘ON’.
So in order to make preferences user specific in liferay, add following entries to liferay-portlet.xml :
<portlet> .... <preferences-unique-per-layout>false</preferences-unique-per-layout> <preferences-owned-by-group>false</preferences-owned-by-group> .... </portlet>
Do these changes and redeploy portlet, now Bob’s preferences are for Bob only !!!
Useful Eclipse Shortcuts for Java Developer
Eclilpse is one of the most popular IDE for JAVA based development projects. As we know every technologies and tools comes with its own learning curve. Althaugh eclilpse is very easy to use but still lot of the developers are not using it at its fullest capacity.
Here in this post I will show some very useful Eclipse shortcuts which will be useful for you in your day to day development.
- Get rid of manual Import statements : Organize Imports ( Ctrl+Shift+O)
After you write a line of your code you may need to Impot classed used in your code.Otherwise eclipse will show errors as you can see in this image. Organize Import will import classes if found from class path of your project. - Quickly Go to File : Open Resource ( Ctrl+Shift+R)
Project we have several packages, in order to go to the particular file developer need to traverse to file through packages/folders in Navigator /Package view.For example I am looking for BaseModelImpl.java file instead of going through all packages/folders
Do : Open Resource ( Ctrl + Shift + R ) and type BaseImpl it will show all files starts with BaseImpl you can select the file you need and press OK to open. It supports RegEx so you can type like Ba*Im*.java also to filter your search.It can locate any file in your project not limited to .java files. - Quickly locate JAR which contains ‘the class’ : Open Type ( Ctrl+Shift+T)
Several times I need to know which particular JAR contains the class I am interested in. For Example I have couple of projects in workspace and I copy paste few lines from other project.Its giving errors as Eclipse not able to resolve classes. As its working in other projects, I need to know which JAR file this class contains and I need to copy that jar file to my project and/or set in classpath. - Jump to Last Edit Location : (Ctrl+Q)
Working with multiple source files is reality of development . When you are working with multiple source files and need to know in which file you made last changes you can easily Jump to last Edit Location using ( Ctrl+ Q). - Locate where this method is reffered in projects : (Ctrl+Shift+G) (Quick Search)
In order to know where this particular method/variable is reffered not only in this project but other projects of workspace also. Select method in Editor and do Ctrl+Shift+G. In search view Eclipse will search its references in all projects in current workspace.