+ All Categories
Home > Investor Relations > Introduction to Portlets using Liferay Portal (Part 2)

Introduction to Portlets using Liferay Portal (Part 2)

Date post: 23-Aug-2014
Category:
Upload: rivetlogic
View: 16,338 times
Download: 0 times
Share this document with a friend
Description:
Presentation about Portlets and Liferay Portal held at Costa Rica Java Users Group
Popular Tags:
54
ARTISANS OF OPEN SOURCE Rivet Logic Corporation 11410 Isaac Newton Square N. Suite 210 Reston, VA 20190, USA Ph: 703.955.3480 Fax: 703.234.7711 Rivet Logic Costa Rica SRL Costa Rica Developer's Forge Edificio María Luisa, 3A office Paseo Colón, San José, Costa Rica Ph: (506) 2256-1024 Fax: (506) 2256-1024 Introduction to Portlets using Liferay Portal (Part 2) By: Aníbal Gómez-Estrada http://rivetlogic.com/web/agomez October 19 th , 2011
Transcript
Page 1: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE

Rivet Logic Corporation 11410 Isaac Newton Square N. Suite 210 Reston, VA 20190, USA Ph: 703.955.3480 Fax: 703.234.7711

Rivet Logic Costa Rica SRL Costa Rica Developer's Forge Edificio María Luisa, 3A office Paseo Colón, San José, Costa Rica Ph: (506) 2256-1024 Fax: (506) 2256-1024

Introduction to Portlets using Liferay Portal (Part 2)

By: Aníbal Gómez-Estrada http://rivetlogic.com/web/agomez

October 19th, 2011

Page 2: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Rivet Logic Overview

•  Award-winning consulting and systems integration firm focused on enabling open source –based software solutions for content management, collaboration and community:

–  Innovator of the Year: JBoss (2008) –  Solution of the Year: Alfresco (2010) –  Platinum Partner: Liferay (2011)

•  We use top-notch open source technology:

•  Company Facts: –  Founded in 2005. Consistently Profitable and Employee-owned. 40+ Consultants –  Headquarters in Virginia, USA. Near-shore office in San José, Costa Rica for two years –  Certified Liferay Partner since 2006:

•  Conduct all public training on East Coast, USA •  Contributor (software, documentation, forums, training material) •  20+ Liferay projects underway or completed!

Page 3: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Agenda

•  Introduction –  Portals and Portlets –  Liferay SDK Plugin Types –  Liferay Service Builder –  Portlets 1.0 (JSR 168)

•  Portlets 2.0 (JSR 286) –  Resource Serving –  Inter-Portlet Communication –  Lifecycle Revisited –  Portlet Filters and PortletURL Listeners –  Enhancements:

•  Servlet Programming Features •  Annotations •  Tag Libraries

•  Conclusion –  Questions and Answers –  References

•  Announcements –  JSF 2.0 Portlets using Liferay Portal is Available Now! –  Rivet Logic Is Hiring!

Page 4: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE

Introduction

Page 5: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portals and Portlets

In a Nutshell

A Portal is designed to be a single web-based environment where all users applications

run integrated together in a

systematic way”

Liferay Portal is a Portlet Container and Portal Server

Platform and environment to run/administer web sites

and to integrate portlets

Portal Architecture:

Page 6: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Liferay SDK Plugin Types

Themes

•  Themes customize the overall structure and look and feel of the Portal pages and are based on HTML, CSS and Velocity/FreeMarker

•  Theme Plugins are based on a pre-made theme which gives the site minimal structure (either unstyled or styled) •  Customizations are overlaid against the “base theme” with a overwriting mechanism

and differentiation scheme •  Provide control over everything: HTML, CSS and images inside portlets (box) and

outside (page) and positioning/behavior of the top navigation elements

•  Deployed Themes can be used at level different levels: the overall site, a community/organization or a single page

More Info: http://www.liferay.com/community/wiki/-/wiki/Main/Themes

Page 7: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Liferay SDK Plugin Types (2)

Layout Templates •  Layout Templates control how portlets are arranged

on a Portal page and are created with a combination of HTML, CSS and Velocity

•  They make up the body of the page, the large area where portlets can be dragged and dropped into

•  Allow portlets to be embedded into templates •  Deployed Layout Templates are used at page level

•  For Instance:

More Info: http://www.liferay.com/web/guest/community/wiki/-/wiki/Main/Layout+Template

Page 8: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Liferay SDK Plugin Types (3)

Hooks •  Hooks allow to hook custom code at different extension

points in order to either change, override or extend: •  Display: JSPs and Language Properties •  Behavior: Portal Server Lifecycle Events, Services, Model Listeners

and Portal Properties

•  Hook Plugins are Java code –based and they are hot-deployable, as well as, Themes, Layout Templates and Portlet Plugins do!

More Info: http://www.liferay.com/community/wiki/-/wiki/Main/Portal+Hook+Plugins

Page 9: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Liferay SDK Plugin Types (4)

Portlets •  Portlets are componentized

user-facing applications that generate a fragment of the Portal page

In this presentation, you will learn more about what Portlet Plugins are!

•  For now, let’s take a look at some of the portlets available for Liferay Portal..

More Info: http://www.liferay.com/community/wiki/-/wiki/Main/Out+of+The+Box+Portlets

Page 10: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Liferay SDK Plugin Types (5)

Ext •  Ext allow to extend/override built-in code in special

scenarios that can not be met by another plugin types: •  Easily extensible: Liferay Portal is implemented on top of Spring,

Hibernate and Struts/Tiles, so custom code can be plugged in very easily •  Complete control: It allows access to internal APIs or even overwriting

files/classes provided in the Liferay core •  To be carefully used: it is a powerful tool that comes with a cost in terms of

complexity and maintenance!

•  Ext Plugins are NOT hot-deployable! –  Require server restart –  Can not be un-deployed

More Info: https://www.liferay.com/community/wiki/-/wiki/Main/Ext+Plugin

Page 11: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Liferay Service Builder

•  Service Builder is a tool built by Liferay to automate the creation of Services, Models and Persistence –related interfaces and classes relying on Liferay API, Spring and Hibernate: •  Input: an XML file specifying the structure of Model classes and data-storage –related

operations

•  Ouput: a service JAR that can be exposed either at a global or local (ie. Portlet plugin) levels and a set of implementation classes with beans and basic logic generated for the Model and Service/Persistence classes

•  When specified, Service Builder also generates Javascript stubs for remote access (ie. client side / browser)!

More Info: http://www.liferay.com/community/wiki/-/wiki/Main/Service+Builder

Page 12: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet 1.0 (JSR 168)

•  JSR 168 in a Nutshell: –  Portlet Container Contract and Portlet Lifecycle –  Packaging and Deployment –  Portlet Modes and Window States –  Portlet Preferences Management –  JSP Support –  User Information and Security –  Localization and Caching

•  JSR 168 defined the overall UI component model and provided a few support for building integrated/coordinated composite applications. However, “portlets are islands” in JSR 168: –  Can not generate non-markup content –  Can not communicate with other portlets –  Can not influence the portal page

Page 13: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE

Portlet 2.0 (JSR 286)

Page 14: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet 2.0 (JSR 286)

•  JSR 286 addresses limitations identified by many portal vendors that caused custom solutions and not portable to be placed in their products –  Released in June, 2008 –  Expert Group: IBM, ASF, Oracle, BEA, Liferay, among others

•  Features introduced in JSR 286’s Portlet API also fill some gaps with related technologies, such as J2EE 1.4, WSRP, Servlets, JSF, among others

•  JSR 286 mainly addresses following topics: –  Resource Serving * –  Inter-Portlet Communication: Event-Notification and Public Render

Parameters * –  Portlet Filters and PortletURL Listeners * –  Servlet Programming Model Features * –  Enhancement on Annotations, JSP support, Portlet Modes, Caching *

Page 15: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving

•  In JSR 168, dynamically generated resources could not be directly served from a portlet instance. An additional servlet was needed to serve the resources: –  Disadvantages: Out of Portal’s Scope (No Access to render parameters, portlet mode,

window state, portlet preferences, portlet session, etc). Not under Portal access control (Servlet to be secured separately)

–  Advantages: less overhead because the request does not have to pass through the additional portal framework. Adequate when serving large media streams…

•  JSR 286 introduces Resource Serving as a lifecycle operation that is dispatched directly from corresponding portlet instance: –  Normally occurs after a render call and can be used to implement AJAX use cases –  Does not generate a full new portal page. Returned content not aggregated with another

markup. The resource response allows full control over output stream –  Cannot set new render parameters, portlet mode, or window state since the portal

does not have a chance to update other parts of the page

•  During a Resource Request, a portlet implementing ResourceServingPortlet interface can create dynamic resources through serveResource() method

•  Portlet API provide Resource URLs for Resource Serving requests. They are created with RenderResponse.createResourceURL() and trigger lifecycle serveResource() method. ResourceURLs can be set with params as other URLs

Page 16: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving (2)

•  Let’s create a new JSP-based Portlet which returns a greeting on Ajax call: File: /WEB-INF/src/com/sample/jsp/portlets/JSPPortlet.java package com.sample.jsp.portlets;

import java.io.IOException;import java.io.OutputStream;import javax.portlet.*;

public class JSPPortlet extends javax.portlet.GenericPortlet {

@Override protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { PortletRequestDispatcher rd = getPortletContext().getRequestDispatcher("/html/view.jsp"); rd.include(request,response); }

@Override public void serveResource(ResourceRequest request, ResourceResponse response) throws PortletException, IOException { OutputStream stream = response.getPortletOutputStream(); response.setContentType("text/html");

stream.write( String.format( "%1$s (Ajax - %2$s)!!”, request.getParameter("ajax-parameter-greeting"), Math.random() ).getBytes() ); }}

Page 17: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving (3)

•  Now, let’s create the JSP page invoking the portlet via Ajax: File: /html/view.jsp

<%@ page session="false" contentType="text/html; charset=ISO-8859-1" %><%@ page import="javax.portlet.*"%><%@ taglib uri='/WEB-INF/tld/liferay-portlet.tld' prefix='portlet'%>

<portlet:defineObjects/>

<portlet:resourceURL var="resourceUrl"> <portlet:param name="ajax-parameter-greeting" value="Hello World from Resource Serving Param" /></portlet:resourceURL><p> <input type="button" value='Ajax!' title='<%=resourceUrl%>’ onclick="javascript:ajaxHelloWorld('<%=resourceUrl%>');” /></p><div id="msg_display">The data from the server will go here</div>

<script type="text/javascript"> /* PLEASE LOOK AT NEXT SLIDE */</script>

Page 18: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving (4)

•  Now, let’s create the JSP page invoking the portlet via Ajax (2): File: /html/view.jsp ...<script type="text/javascript">function ajaxHelloWorld(url){ var request = createXMLHttpRequest(); var callback = function() { var msg_display = document.getElementById("msg_display"); if (request.readyState == 4) { if (request.status == 200) { msg_display.innerHTML = request.responseText; } else { msg_display.innerHTML = "ERROR: "+ request.statusText; } } }; request.onreadystatechange = callback; request.open("GET", url, true); request.send();}

function createXMLHttpRequest() { var request; if (window.XMLHttpRequest) { request = new XMLHttpRequest(); } else if (window.ActiveXObject) { try { request = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { request = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) {} } } return request;}</script>

Page 19: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving (5)

•  Finally, let’s add the portlet in corresponding deployment descriptors File: /WEB-INF/portlet.xml <portlet-app ...> ... <portlet> <portlet-name>jsp-hello-world-portlet</portlet-name> <display-name>JSP 2.0 Hello World Portlet</display-name> <portlet-class>com.sample.jsp.portlets.JSPPortlet</portlet-class>

<supports> <mime-type>text/html</mime-type> </supports>

<portlet-info> <title>JSP 2.0 Hello World Portlet</title> <short-title>JSP 2.0 Hello World Portlet</short-title> <keywords>JSP 2.0 Hello World Portlet</keywords> </portlet-info> </portlet> ...</portlet-app>

File: /WEB-INF/liferay-portlet.xml <liferay-portlet-app> <portlet> <portlet-name>jsp-hello-world-portlet</portlet-name> <icon>/icon.png</icon> <instanceable>true</instanceable> </portlet></liferay-portlet-app>

File: /WEB-INF/liferay-display.xml <display> <category name="category.sample"> <portlet id=”jsp-hello-world-portlet" /> </category></display>

Page 20: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving (6)

•  After re-deploying our Portlet plugin and clicking portlet’s button:

Page 21: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Resource Serving (7)

•  An additional resource ID can be set on the resource URL that clearly identifies the resource through ResourceURL.setResourceID() method, such as: –  resourceUrl.setResourceID("WEB-INF/jsp/xmlcontent.jspx"); –  When extending GenericPortlet, a serveResource call is automatically dispatched to the JSP,

which can then make use of the portlet state information by including the portlet tag library

•  Serving static resources using the portlet's serveResource() method causes unnecessary performance overhead: –  Static resources like image files packaged in the portlet WAR should normally be

referenced with static resource URLs, such as: String url = response.encodeURL(request.getContextPath()+"/icons/myimage.gif");

•  In contrast to RenderURLs, all HTTP methods (GET, POST or DELETE) can be leveraged with ResourceURLs (not only GET) which means: –  Methods to change state can be used in the serveResource() call. But, changes should

be limited to private state of portlet: Portlet-scoped session and Portlet Preferences –  State that affects other portlets should not be modified because the portal

framework has no chance to update another portions of the page on serveResource()

Page 22: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications

•  In JSR 168, the only way to achieve communication between portlets was through portlet session. Only possible with portlets in same web-app…

•  JSR 286 provides a loosely coupled publish/subscribe model that allows portlets in different web applications to send and receive events

•  An event is a lifecycle operation that occurs before the rendering phase and allow portlets to respond on actions or state changes

•  Descriptor portlet.xml must declare events and define what portlets are allowed to produce and consume them: –  Event name is represented as QName (Namespace + Localpart) to identify it uniquely –  Event payload (argument) is represented by a java.io.Serializable class

•  During action and event lifecycle operations, a portlet can publish events through inherited StateAwareResponse’s setEvent() method

•  During event lifecycle operation, a portlet implementing EventPortlet interface can handle events through processEvent() method

Page 23: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (2)

•  Let's create a new "Hello World" portlet which issues an event once its action button is clicked: File: /WEB-INF/src/com/sample/generic/portlets/HelloWorldPortlet.java package com.sample.generic.portlets;

import java.io.IOException;import java.io.PrintWriter;import javax.portlet.*;import javax.xml.namespace.QName;

public class HelloWorldPortlet extends javax.portlet.GenericPortlet { @Override protected void doView(RenderRequest request, RenderResponse response) throws PortletException, IOException { PrintWriter writer = response.getWriter(); writer.write( String.format( "<form action='%1$s' method='POST'>" + "<input type='submit' value='Change!' />"+ "</form>", response.createActionURL().toString() ) ); }

@Override public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { response.setEvent( new QName("http://sample.com/events", "ipc.speak.world"), "The Event PayLoad!!" ); }}

Page 24: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (3)

•  Let's create a new "Hello World" portlet which issues an event once its action button is clicked: File: /WEB-INF/src/com/sample/generic/portlets/GoodbyeWorldPortlet.java package com.sample.generic.portlets;

import java.io.IOException;import java.io.PrintWriter;import javax.portlet.*;

public class GoodbyeWorldPortlet implements javax.portlet.Portlet, javax.portlet.EventPortlet { public void init(PortletConfig config) throws PortletException {} public void destroy() {}

public void render(RenderRequest request, RenderResponse response)throws PortletException, IOException {

PrintWriter writer = response.getWriter();

String renderParameter = request.getParameter("render-param-greeting"); writer.write( String.format(

"<p>%1$s</p>”, (renderParameter != null) ? renderParameter : "Waiting for Greeting...” ) ); }

public void processAction(ActionRequest request, ActionResponse response)throws PortletException, IOException {}

public void processEvent(EventRequest request, EventResponse response) throws PortletException, IOException { Event event = request.getEvent(); if ("{http://sample.com/events}ipc.speak.world".equals(event.getQName().toString()) && "The Event PayLoad!!".equals(event.getValue())) { response.setRenderParameter("render-param-greeting", "Goodbye World!!"); } }}

Page 25: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (4)

•  Let’s now declare the event and add the portlets in the standard deployment descriptor: File: /WEB-INF/portlet.xml <portlet-app ...> ... <portlet> <portlet-name>generic-hello-world-portlet</portlet-name> <display-name>Generic 2.0 Hello World Portlet</display-name> <portlet-class>com.sample.generic.portlets.HelloWorldPortlet</portlet-class>

<supports> <mime-type>text/html</mime-type> </supports>

<portlet-info> <title>Generic 2.0 Hello World Portlet</title> <short-title>Generic 2.0 Hello World Portlet</short-title> <keywords>Generic 2.0 Hello World Portlet</keywords> </portlet-info>

<supported-publishing-event> <qname xmlns:x="http://sample.com/events">x:ipc.speak.world</qname> </supported-publishing-event> </portlet> ... <event-definition> <qname xmlns:x="http://sample.com/events">x:ipc.speak.world</qname> <value-type>java.lang.String</value-type> </event-definition></portlet-app>

Page 26: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (5)

•  Let’s now declare the event and add the portlets in the standard deployment descriptor (2): File: /WEB-INF/portlet.xml <portlet-app ...> ... <portlet> <portlet-name>generic-goodbye-world-portlet</portlet-name> <display-name>Generic 2.0 Goodbye World Portlet</display-name> <portlet-class>com.sample.generic.portlets.GoodbyeWorldPortlet</portlet-class>

<supports> <mime-type>text/html</mime-type> </supports>

<portlet-info> <title>Generic 2.0 Goodbye World Portlet</title> <short-title>Generic 2.0 Goodbye World Portlet</short-title> <keywords>Generic 2.0 Goodbye World Portlet</keywords> </portlet-info>

<supported-processing-event> <qname xmlns:x="http://sample.com/events">x:ipc.speak.world</qname> </supported-processing-event> </portlet> ...</portlet-app>

Page 27: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (6)

•  Finally, let’s add liferay -specific configuration for our new Portlets: File: /WEB-INF/liferay-portlet.xml <liferay-portlet-app> ... <portlet> <portlet-name>generic-hello-world-portlet</portlet-name> <icon>/icon.png</icon> <instanceable>true</instanceable> </portlet> <portlet> <portlet-name>generic-goodbye-world-portlet</portlet-name> <icon>/icon.png</icon> <instanceable>true</instanceable> </portlet> ...</liferay-portlet-app>

File: /WEB-INF/liferay-display.xml <display> <category name="category.sample"> ... <portlet id="generic-hello-world-portlet" /> <portlet id="generic-goodbye-world-portlet" /> ... </category></display>

Page 28: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (7)

•  After re-deploying our Portlet plugin, adding both portlets to the same page and click on “Hello World” portlet’s button…

Page 29: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (8)

•  JSR 286 defines some additional features for event definition and declaration available from portlet.xml:

–  Default namespace: a namespace defined through <default-namespace> element can be applied to all events defined only with a local name (<name> element)

–  Aliases: an alternative name defined through <alias> element can be used to coordinate communication between portlets that need to use different names for same event

–  Wildcards: <supported-processing-event> and <supported-publishing-event> elements can use trailing-dot -based wildcards to match events names which local part is defined in hierarchical manner using the dot (.) as a separator. For example: •  “x:foo.event.” can match “x:foo.event.one” and “x:foo.event.two”, but not “x:foo.bar.event” •  “x:foo..” can match “x:foo.event.one” and “x:foo.event.two” and “x:foo.bar.event”

Page 30: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Event Notifications (9)

File: /WEB-INF/portlet.xml <portlet-app ...> ... <portlet> <portlet-name>generic-hello-world-portlet</portlet-name> ... <supported-processing-event> <qname xmlns:x="http://sample.com/events">x:ipc..</qname> </supported-processing-event> </portlet> ... <portlet> <portlet-name>generic-goodbye-world-portlet</portlet-name> ... <supported-processing-event> <name>ipc.speak.world</name> </supported-processing-event> </portlet> ... <default-namespace>http://sample.com/events</default-namespace> ... <event-definition> <name>ipc.hello.world</name> <alias xmlns:x="http://sample.com/events">x:ipc.speak.world</alias> <value-type>java.lang.String</value-type> </event-definition> ...</portlet-app>

•  JSR 286 defines some additional features for event definition and declaration available from portlet.xml:

Page 31: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Public Render Parameters

•  In JSR 168, render parameters set in processAction() method are only available in the render phase of the same portlet

•  JSR 286 allows render parameters to be shared across portlets of same web page. They enable coordination between portlets (parameter passing) and avoid the additional process event call

•  Public render parameters are available in all lifecycle methods and can be viewed or changed by other portlets or components

•  Descriptor portlet.xml must declare public render parameters and specify which ones are to be shared for each portlet: –  Name is represented as QName (Namespace + Localpart) to identify it uniquely –  Identifier defines how it can be referenced from different portlets configuration

•  Similarly to Events, features for public render parameters available from portlet.xml: –  Default namespace: a namespace defined through element <default-namespace>

can be applied to all public render parameters defined only with a local name (<name>) –  Aliases: an alternative name defined through element <alias> can be used to

coordinate portlets that need to use different names for same public render parameter

Page 32: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Public Render Parameters (2)

•  Let’s replace mechanism for Inter-Portlet communication through Public Render Parameters: File: /WEB-INF/src/com/sample/generic/portlets/HelloWorldPortlet.java

package com.sample.generic.portlets;

import java.io.IOException;import java.io.PrintWriter;import javax.portlet.*;import javax.xml.namespace.QName;

public class HelloWorldPortlet extends javax.portlet.GenericPortlet { ... @Override public void processAction(ActionRequest request, ActionResponse response) throws PortletException, IOException { response.setRenderParameter ( "render-param-greeting", "Goodbye World from Public Render Parameter!!" ); //response.setEvent //( // new QName("http://sample.com/events", "ipc.speak.world"), "The Event PayLoad!!" //); }}

Page 33: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Public Render Parameters (3)

•  Let’s now declare the public render parameter in the standard deployment descriptor: File: /WEB-INF/portlet.xml

<portlet-app ...> ... <portlet> <portlet-name>generic-hello-world-portlet</portlet-name> ... <supported-public-render-parameter> render-param-greeting </supported-public-render-parameter> </portlet> ... <portlet> <portlet-name>generic-goodbye-world-portlet</portlet-name> ... <supported-public-render-parameter> render-param-greeting </supported-public-render-parameter> </portlet> ... <default-namespace>http://sample.com/events</default-namespace> ... <public-render-parameter> <identifier>render-param-greeting</identifier> <name>ipc.render.world</name> </public-render-parameter> ...</portlet-app>

Page 34: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE IPC: Public Render Parameters (4)

•  After re-deploying our Portlet plugin and clicking on “Hello World” portlet’s button…

Page 35: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Contract and Lifecycle Revisited

•  Request handling sequence after lifecycle methods introduced by JSR 286:

Page 36: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Let’s Take a Break!

Rivet Logic Corporation 11410 Isaac Newton Square N. Suite 210 Reston, VA 20190, USA Ph: 703.955.3480 Fax: 703.234.7711

Rivet Logic Costa Rica SRL Costa Rica Developer's Forge Edificio María Luisa, 3A office Paseo Colón, San José, Costa Rica Ph: (506) 2256-1024 Fax: (506) 2256-1024

Introduction to Portlets using Liferay Portal (Part 2)

By: Aníbal Gómez-Estrada http://rivetlogic.com/web/agomez

October 19th, 2011

Page 37: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet Filters

•  JSR-268 introduces Portlet Filters as a means to intercept any lifecycle call to a portlet and manage custom behavior in centralized way

•  Portlet Filters are reusable pieces of code that can transform content in both request and response of the portlet

•  Functionality implementable through Portlet Filters: –  Pass additional data into the portlet (as attributes or parameters) –  Output filtering for security enforcement or markup compliance –  Collecting diagnostic information –  Bridging between Web application frameworks

•  Portlet Filter model is based on the Servlet Filter model...

Page 38: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet Filters (2)

•  Depending on type of lifecycle call to be filtered, a Portlet Filters must implement one of the following interfaces: –  javax.portlet.filter.RenderFilter –  javax.portlet.filter.ActionFilter –  javax.portlet.filter.EventFilter –  javax.portlet.filter.ResourceFilter

•  Portlet Filters have the following lifecycle: –  Initialization: init() called when filter is instantiated. FilterConfig

holding init parameters and PortletContext is provided for resource initialization

–  Deinitialization: destroy() called when filter is being taken out of service. To contain logic that cleans it up (ie, memory, file handles, threads, etc)

–  Filtering: doFilter () called each time an action request/response pair is passed through the chain due to a client request

Page 39: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet Filters (3)

•  At runtime, a filter chain of all filters is applied: –  Each filter gets the current request/response and the filter chain –  After doing its pre/post processing, the filter can either:

•  Terminate the request processing, or •  Call the next element in the chain by passing in either the received request and

response, or wrapped versions

–  The last element in the filter chain is the portlet itself!

•  Descriptor portlet.xml must define: –  Filters with a name, intended lifecycle phase (ACTION_PHASE,

EVENT_PHASE, RENDER_PHASE or RESOURCE_PHASE), PortletFilter class and init parameters

–  Filter mappings by associating filters to portlets. Order of filter-mapping defines the order in which they are applied at runtime

Page 40: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet Filters (4)

•  Let’s create a PortletFilter to agregate content at beginning/end on render response: File: /WEB-INF/src/com/sample/generic/filters/RenderFilter.java package com.sample.generic.filters;

import java.io.IOException;import java.io.PrintWriter;import javax.portlet.*;import javax.portlet.filter.*;

public class RenderFilter implements javax.portlet.filter.RenderFilter {

private String prologueMessage, epilogueMessage;

public void init(FilterConfig config) throws PortletException { prologueMessage = config.getInitParameter("filter-init-parameter-prologue"); epilogueMessage = config.getInitParameter("filter-init-parameter-epilogue"); } public void destroy() { }

public void doFilter(RenderRequest request,RenderResponse response, FilterChain chain) throws IOException, PortletException {

PrintWriter writer = response.getWriter();

writer.write(String.format("<p>%1$s</p>", prologueMessage));

chain.doFilter(request, response);

writer.write(String.format("<p>%1$s</p>", epilogueMessage)); }}

Page 41: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet Filters (5)

•  Now, let’s define/enable our PorletFilter on each existing portlet:

File: /WEB-INF/portlet.xml <portlet-app ...> ... <portlet>...</portlet> ... <filter> <filter-name>render-filter</filter-name> <filter-class>com.sample.generic.filters.RenderFilter</filter-class> <lifecycle>RENDER_PHASE</lifecycle> <init-param> <name>filter-init-parameter-prologue</name> <value>Good Morning,</value> </init-param> <init-param> <name>filter-init-parameter-epilogue</name> <value>Have a Good Day!</value> </init-param> </filter> <filter-mapping> <filter-name>render-filter</filter-name> <portlet-name>generic-hello-world-portlet</portlet-name> <portlet-name>generic-goodbye-world-portlet</portlet-name> <portlet-name>jsp-hello-world-portlet</portlet-name> </filter-mapping> ... <default-namespace>...</default-namespace> ...</portlet-app>

Page 42: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet Filters (6)

•  After re-deploying our Portlet plugin:

Page 43: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet URL Listeners

•  JSR-268 introduces Portlet URL Listeners as a means to intercept URLs in centralized way, before they get generated (ie. when methods toString() or write() are called on URLs)

•  Functionality implementable through Portlet URL Listeners is around managing specific Portlet –related properties on URLs: –  Parameters, portlet mode, window state –  Security, Cache level of resources, etc

•  In order to receive a callback whenever a Portlet URL is generated, Portlet URL Listeners must implement interface javax.portlet.PortletURLGenerationListener with methods: –  filterRenderURL() for RenderURLs –  filterActionURL() for ActionURLs –  filterResourceURL() for ResourceURLs

Page 44: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet URL Listeners (2)

•  Descriptor portlet.xml must register Portlet URL Listeners with a <listener> element for each PortletURLGenerationListener class

•  Order of <listener> elements defines the order they are applied at runtime

•  Let’s create a Portlet URL Listener to override parameter value for Ajax call on previously created Portlet: File: /WEB-INF/src/com/sample/generic/listeners/ResourceURLListener.java package com.sample.generic.listeners;

import javax.portlet.*;

public class ResourceURLListener implements PortletURLGenerationListener {

public void filterActionURL(PortletURL actionURL) { }

public void filterRenderURL(PortletURL renderURL) { }

public void filterResourceURL(ResourceURL resourceURL) { resourceURL.setParameter ( "ajax-parameter-greeting", "Hello World from Resource URL Listener" ); }}

Page 45: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Portlet URL Listeners (3)

•  Now, let’s define/enable our PorletFilter on each existing portlet: File: /WEB-INF/portlet.xml <portlet-app ...> ... <public-render-parameter>...</public-render-parameter> ... <listener> <display-name>Hello World Portlet URL Listener</display-name> <listener-class>com.sample.generic.listeners.ResourceURLListener</listener-class> </listener> ...</portlet-app>

After re-deploying our Portlet plugin and clicking on Portlet’s button:

Page 46: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Servlet Programming Features

•  If compared to Servlets, JSR-168 restricted the portlet programming model in some areas because some Servlet model features -assuming only one component on the page- are not easily applied on Portlets

•  JSR-268 provides nearly the same capabilities as the Servlet programming model plus the portlet specific extensions…

•  Document head section elements, HTTP headers and Cookies: JSR-268 allows the portlet to contribute to sections of portal page outside its portlet window: –  Document head section elements: a two-part render call (RENDER_HEADER and

RENDER_MARKUP) is enabled in order portlets can return content outside the portlet window (ie. HTML ones such as meta, link, or style) through GenericPortlet.doHeaders()

–  HTTP Headers (ie. app-specific Pragma headers) via PortletResponse.setProperty() –  Cookies through PortletResponse.addProperty() at the response of each life-cycle method

(processAction, processEvent, render, and serveResource): •  Cookies are not guaranteed to be shared across different portlets and may be stored by the portal (not at the client) •  To set cookies in the render method, the renderHeaders option should be turned on and the cookies should be set in the

RENDER_HEADERS part by using overriding GenericPortlet.doHeaders()

•  Dispatching to Servlets and JSPs: A portlet can invoke servlets and JSPs in all lifecycle methods by using methods include() or forward() via a request dispatcher (PortletContext.getRequestDispatcher()): –  Action/event can be dispatched to logic written in a servlet, or do forward in serving resource –  Servlet request/response objs given to the servlet/JSP are based on portlet request/response:

•  Attributes set in the portlet request are available in the included servlet request •  The portlet and the included servlet or JSP share the same output stream •  Attributes set in the portlet session are accessible from the servlet session and vice versa

Page 47: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Annotations

•  JSR-268 introduces Annotations for directly dispatching requests when using GenericPortlet to ease configuration pain

–  Annotation @ProcessEvent for event calls @ProcessEvent(qname="{http://sample.com/events}ipc.speak.world")

public void processSpeakWorldEvent(EventRequest req, EventResponse res){...}

–  Annotation @ProcessAction for action calls via a ActionURL with parameter "javax.portlet.action” set:

@ProcessAction(name="speakWorld”) public void speakWorld(ActionRequest request, ActionResponse response){...}

–  Annotation @RenderMode for render calls for a corresponding Portlet Mode

@RenderMode(name="VIEW") public void speakWorld(RenderRequest request, RenderResponse response){...}

Page 48: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Tag Libraries

•  JSR-268 provides new tags to ease JSP development: –  <portlet:resourceURL>: build ResourceURL refering back to the portlet –  Attributes copyCurrentRenderParameters and escapeXML on

RenderURL, ActionURL and ResourceURL –  <portlet:namespace>: returns unique value for the current Portlet window

•  Since Portlet’s markup is aggregated in same page, name of items that should be unique should be “namespaced” through PortletRequest.getNamespace(): –  Returned value is same/preserved for the entire lifetime of the Portlet window –  To be used to prefix names that should be unique (ie. html ids/names,

javascript functions/variables, etc)

<script type="text/javascript”> … function <portlet:namespace/>ajaxHelloWorld(url){...} …

</script>… <input type="button" value='Ajax!' title='<%=resourceUrl%>’ onclick="javascript:<portlet:namespace/>ajaxHelloWorld('<%=resourceUrl%>');”/>

Page 49: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE

Conclusion

Page 50: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Questions?

Rivet Logic Corporation 11410 Isaac Newton Square N. Suite 210 Reston, VA 20190, USA Ph: 703.955.3480 Fax: 703.234.7711

Rivet Logic Costa Rica SRL Costa Rica Developer's Forge Edificio María Luisa, 3A office Paseo Colón, San José, Costa Rica Ph: (506) 2256-1024 Fax: (506) 2256-1024

Introduction to Portlets using Liferay Portal (Part 2)

By: Aníbal Gómez-Estrada http://rivetlogic.com/web/agomez

October 19th, 2011

Page 51: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE References

JSR 286: Portlet Specification 2.0

http://www.bluesunrise.com/portlet-api/javax/portlet/package-summary.html

http://www.ibm.com/developerworks/websphere/library/techarticles/0803_hepper/0803_hepper.html

http://developers.sun.com/portalserver/reference/techart/jsr286/jsr286.html

http://download.oracle.com/docs/cd/E15919_01/wlp.1032/e14244/javaportlets.htm#BCGIBGBJ

http://www.liferay.com

Page 52: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE

Announcements

Page 53: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Available At My Blog!

JSF 2.0 Portlets using Liferay Portal Available At My Blog!

http://rivetlogic.com/web/agomez/

Contents Introduction to Portlet Bridges Setup and Hello World Portlet

Internationalization Actions and Navigation

Portlet Preferences Inter-Portlet Communication

Page 54: Introduction to Portlets using Liferay Portal (Part 2)

ARTISANS OF OPEN SOURCE Rivet Logic Is Hiring!

We are hiring! Java developers – [email protected]

•  Award-winning consulting and systems integration firm focused on enabling open source –based software solutions for content management, collaboration and community:

–  Innovator of the Year: JBoss (2008) –  Solution of the Year: Alfresco (2010) –  Platinum Partner: Liferay (2011)

•  We use top-notch open source technology:

•  Company Facts: –  Founded in 2005. Consistently Profitable and Employee-owned. 40+ Consultants –  Headquarters in Virginia, USA. Near-shore office in San José, Costa Rica for two years –  Certified Liferay Partner since 2006


Recommended