Portlet Preferences in Liferay and some simple code snippets is today’s topic . Portlet preferences is nothing but name-value pair. Portlet preferences are intended to store basic configuration data for portlets. It is not the purpose of the portlet preferences to replace general purpose databases.
i) Preferences is some sort of data and this data is key-value pair in nature.
ii) Each portlet in Liferay has its own preferences.
iii) Portlet Preferences are stored in portletpreferences table in Liferay Portal.
iv) Most of the time we don’t pay attention to portlet preferences. But portletpreferences table in liferay often get updated behind the scene.
v) Say you add a portlet in a page, a new row will be added in portletpreferences table. Similarly remove a portlet from a page, a row will be removed the table. This is not the end of the story. There are many more interesting facts.
vi) There are many portlets in Liferay which gives nice UI to configure portlet preferences in the run time. For example setup section of portlet configuration page is the place where we deal with portlet preferences in the run time.
Few Code Snippets
1. Defining Portlet Preferences in portlet.xml
We can define portlet preferences in portlet.xml file of a portlet. Below is the sample
<portlet-preferences> <preference> <name>Currency</name> <value>INR</value> <value>SAR</value> <value>USD</value> </preference> <preference> <name>StockSymbol</name> <value>AD</value> </preference> </portlet-preferences>
• As explained before preferences are nothing but key and value pairs.
• As shown in the above code we have defined two preferences. One is Currency and another is StockSymbol.
• A key can have one value or multiple values or null value. The key Currency has multiple values as defined in the xml.
• According to DTD the portlet-preferences tag should start after portlet-info tag.
2. Retrieve Portlet Preferences
Portlet Preferences in JSP:
<%@ taglib uri="http://java.sun.com/portlet_2_0" prefix="portlet" %> <portlet:defineObjects /> <% String stock = portletPreferences.getValue("StockSymbol", ""); out.println(stock); String[] currencies= portletPreferences.getValues("Currency",new String[]{}); for(String currency:currencies){ out.println(currency); } %>
In JSP portletPreferences object directly available if we we use <portlet:defineObjects />
Portlet Preferences in Portlet class:
import java.io.IOException; import javax.portlet.ActionRequest; import javax.portlet.ActionResponse; import javax.portlet.PortletException; import javax.portlet.PortletPreferences; import javax.portlet.RenderRequest; import javax.portlet.RenderResponse; import com.liferay.util.bridges.mvc.MVCPortlet; public class SamplePortlet extends MVCPortlet { @Override public void doView(RenderRequest renderRequest, RenderResponse renderResponse) throws IOException, PortletException { /** * Preferences object from renderRequest */ PortletPreferences portletPreferences = renderRequest.getPreferences(); String stockSymbol = portletPreferences.getValue("StockSymbol", ""); System.out.println(stockSymbol); super.doView(renderRequest, renderResponse); } public void someProcessAction(ActionRequest actionRequest, ActionResponse actionResponse) { /** * Preferences object from action request */ PortletPreferences portletPreferences = actionRequest.getPreferences(); String stockSymbol = portletPreferences.getValue("StockSymbol", ""); System.out.println(stockSymbol); } }
3. As a developer we don’t bother how portal retrieves preferences
Working with portlet preferences we never bother about database persistence.Its portal’s responsibility to do the job. We can retrieve portlet preferences from any of the portlet life cycle methods
render
serveResource
processAction
processEvent
4. Read only portlet preferences
The portlet preferences defined in portlet.xml so far is not read only. This is the default behavior. That means at any point of time we can retrieve the portlet preference and modify it. If a preference is read only then we can not modify the portlet preference. For example in below StockSymbol is read only preference. The value of the StockSymbol key can not be changed at any cost.
<portlet-preferences> <preference> <name>Currency</name> <value>INR</value> <value>SAR</value> <value>USD</value> </preference> <preference> <name>StockSymbol</name> <value>AD</value> <read-only>true</read-only> </preference> </portlet-preferences>
If we try to modify the preferences it will throw exception
10:32:32,931 ERROR [http-bio-8080-exec-74][render_portlet_jsp:132] null javax.portlet.ReadOnlyException: StockSymbol at com.liferay.portlet.BasePreferencesImpl.setValue(BasePreferencesImpl.java:167)
5. Update Portlet preferences in the run time
At any point of time we can update existing portlet preferences in the run time if its not read only. To update preference first retrieve it, set some value and call store method. For example
PortletPreferences portletPreferences = actionRequest.getPreferences(); String stockSymbol = portletPreferences.getValue("StockSymbol", ""); portletPreferences.setValue("StockSymbol", "MAR"); portletPreferences.store();
Be careful after setting new value we must call store method. Otherwise there will not be any effect of setting any new value.
6. Add preference key at run time
In any one of the portlet life cycle method we can add new preferences key. Its just similar to to point 5. In below we are adding new key
PortletPreferences portletPreferences = actionRequest.getPreferences(); portletPreferences.setValue("new-key", "any-value"); portletPreferences.store();
7. Preferences Validator
Some times we need to validate preferences before storing. To validate preference implements the interface PreferencesValidator and register it in the portlet.xml using <preferences-validator> tag. Whenever we make call the store() method the validate() method will be called of the Validator. From the validate method throw ValidatorException.
<portlet-preferences> <preference> <name>Currency</name> <value>INR</value> <value>SAR</value> <value>USD</value> </preference> <preference> <name>StockSymbol</name> <value>AD</value> </preference> <preferences-validator>com.demo.SamplePreferencesValidator</preferences-validator> </portlet-preferences>
SamplePreferencesValidator.java
import java.util.ArrayList; import java.util.List; import javax.portlet.PortletPreferences; import javax.portlet.PreferencesValidator; import javax.portlet.ValidatorException; public class SamplePreferencesValidator implements PreferencesValidator{ @Override public void validate(PortletPreferences portletPreferences) throws ValidatorException { String stockSymbol = portletPreferences.getValue("StockSymbol", ""); List<String> list = new ArrayList<String>(); list.add(stockSymbol); if(stockSymbol.equalsIgnoreCase("some-bad-value")){ throw new ValidatorException("Bad value of the key",list); } } }