9654467111 Call Girls In Katwaria Sarai Short 1500 Night 6000
Introduction to Portlets using Liferay Portal (Part 2)
1. ARTISANS OF OPEN SOURCE
Introduction to Portlets using Liferay Portal
(Part 2)
By: Aníbal Gómez-Estrada
http://rivetlogic.com/web/agomez
October 19th, 2011
Rivet Logic Corporation Rivet Logic Costa Rica SRL
11410 Isaac Newton Square N. Costa Rica Developer's Forge
Suite 210 Edificio María Luisa, 3A office
Reston, VA 20190, USA Paseo Colón, San José, Costa Rica
Ph: 703.955.3480 Fax: 703.234.7711 Ph: (506) 2256-1024 Fax: (506) 2256-1024
2. Rivet Logic Overview ARTISANS OF OPEN SOURCE
• 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!
3. Agenda ARTISANS OF OPEN SOURCE
• 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!
5. Portals and Portlets ARTISANS OF OPEN SOURCE
In a Nutshell
Portal Architecture:
A Portal is designed to Liferay Portal is a
be a single web-based Portlet Container
environment where all and Portal Server
users applications Platform and
run integrated environment to run/
together in a administer web sites
systematic way” and to integrate portlets
6. Liferay SDK Plugin Types ARTISANS OF OPEN SOURCE
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
7. Liferay SDK Plugin Types (2) ARTISANS OF OPEN SOURCE
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
8. Liferay SDK Plugin Types (3) ARTISANS OF OPEN SOURCE
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
9. Liferay SDK Plugin Types (4) ARTISANS OF OPEN SOURCE
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
10. Liferay SDK Plugin Types (5) ARTISANS OF OPEN SOURCE
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
11. Liferay Service Builder ARTISANS OF OPEN SOURCE
• 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
12. Portlet 1.0 (JSR 168) ARTISANS OF OPEN SOURCE
• 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
14. Portlet 2.0 (JSR 286) ARTISANS OF OPEN SOURCE
• 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 *
15. Resource Serving ARTISANS OF OPEN SOURCE
• 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
16. Resource Serving (2) ARTISANS OF OPEN SOURCE
• 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()
);
}
}
17. Resource Serving (3) ARTISANS OF OPEN SOURCE
• 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>
18. Resource Serving (4) ARTISANS OF OPEN SOURCE
• 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>
19. Resource Serving (5) ARTISANS OF OPEN SOURCE
• 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>
20. Resource Serving (6) ARTISANS OF OPEN SOURCE
• After re-deploying our Portlet plugin and clicking portlet’s button:
21. Resource Serving (7) ARTISANS OF OPEN SOURCE
• 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()
22. IPC: Event Notifications ARTISANS OF OPEN SOURCE
• 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
23. IPC: Event Notifications (2) ARTISANS OF OPEN SOURCE
• 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!!"
);
}
}
24. IPC: Event Notifications (3) ARTISANS OF OPEN SOURCE
• 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!!");
}
}
}
25. IPC: Event Notifications (4) ARTISANS OF OPEN SOURCE
• 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>
26. IPC: Event Notifications (5) ARTISANS OF OPEN SOURCE
• 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>
28. IPC: Event Notifications (7) ARTISANS OF OPEN SOURCE
• After re-deploying our Portlet plugin, adding both portlets to the
same page and click on “Hello World” portlet’s button…
29. IPC: Event Notifications (8) ARTISANS OF OPEN SOURCE
• 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”
30. IPC: Event Notifications (9) ARTISANS OF OPEN SOURCE
• JSR 286 defines some additional features for event definition and
declaration available from portlet.xml:
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>
31. IPC: Public Render Parameters ARTISANS OF OPEN SOURCE
• 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
32. IPC: Public Render Parameters (2) ARTISANS OF OPEN SOURCE
• 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!!"
//);
}
}
33. IPC: Public Render Parameters (3) ARTISANS OF OPEN SOURCE
• 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>
34. IPC: Public Render Parameters (4) ARTISANS OF OPEN SOURCE
• After re-deploying our Portlet plugin and clicking on “Hello World”
portlet’s button…
35. Contract and Lifecycle Revisited ARTISANS OF OPEN SOURCE
• Request handling sequence after lifecycle methods
introduced by JSR 286:
36. Let’s Take a Break! ARTISANS OF OPEN SOURCE
Introduction to Portlets using Liferay Portal
(Part 2)
By: Aníbal Gómez-Estrada
http://rivetlogic.com/web/agomez
October 19th, 2011
Rivet Logic Corporation Rivet Logic Costa Rica SRL
11410 Isaac Newton Square N. Costa Rica Developer's Forge
Suite 210 Edificio María Luisa, 3A office
Reston, VA 20190, USA Paseo Colón, San José, Costa Rica
Ph: 703.955.3480 Fax: 703.234.7711 Ph: (506) 2256-1024 Fax: (506) 2256-1024
37. Portlet Filters ARTISANS OF OPEN SOURCE
• 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...
38. Portlet Filters (2) ARTISANS OF OPEN SOURCE
• 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
39. Portlet Filters (3) ARTISANS OF OPEN SOURCE
• 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
40. Portlet Filters (4) ARTISANS OF OPEN SOURCE
• 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));
}
}
41. Portlet Filters (5) ARTISANS OF OPEN SOURCE
• 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>
42. Portlet Filters (6) ARTISANS OF OPEN SOURCE
• After re-deploying our Portlet plugin:
43. Portlet URL Listeners ARTISANS OF OPEN SOURCE
• 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
44. Portlet URL Listeners (2) ARTISANS OF OPEN SOURCE
• 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"
);
}
}
45. Portlet URL Listeners (3) ARTISANS OF OPEN SOURCE
• 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:
46. Servlet Programming Features ARTISANS OF OPEN SOURCE
• 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
47. Annotations ARTISANS OF OPEN SOURCE
• 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){...}
48. Tag Libraries ARTISANS OF OPEN SOURCE
• 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%>');”
/>
50. Questions? ARTISANS OF OPEN SOURCE
Introduction to Portlets using Liferay Portal
(Part 2)
By: Aníbal Gómez-Estrada
http://rivetlogic.com/web/agomez
October 19th, 2011
Rivet Logic Corporation Rivet Logic Costa Rica SRL
11410 Isaac Newton Square N. Costa Rica Developer's Forge
Suite 210 Edificio María Luisa, 3A office
Reston, VA 20190, USA Paseo Colón, San José, Costa Rica
Ph: 703.955.3480 Fax: 703.234.7711 Ph: (506) 2256-1024 Fax: (506) 2256-1024
51. References ARTISANS OF OPEN SOURCE
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
53. Available At My Blog! ARTISANS OF OPEN SOURCE
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
54. Rivet Logic Is Hiring! ARTISANS OF OPEN SOURCE
We are hiring! Java developers – mcalvo@rivetlogic.com
• 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