46
JSR-168 Portlets and uPortal Matt Young [email protected]

JSR-168 Portlets and uPortal Matt Young [email protected]

  • View
    216

  • Download
    1

Embed Size (px)

Citation preview

JSR-168 Portlets and uPortal

Matt Young

[email protected]

Goals

• Familiarity with portlet architecture

• Familiarity with the services provided to portlets by the spec

• Ability to write useful portlets

• Provide examples that can be used as a cut & paste source for common tasks

• Explore MVC options

Overview

• What’s a portlet?

• What is its relationship with a portal?

• How is it deployed on a web server?

• What deployment descriptors does it need?

• How is the code laid out?

• What services does it provide?

What is a Portlet?

• A portlet produces an HTML fragment that populates a window (or channel) within a portal page

• The portlet can communicate with the portal container

Portals and Portlets

Portal

Tomcat

Application Server

Portlet App

Weather Portlet

Search Portlet

Events Calendar Portlet

Search Controller

Portlet

SearchResultsPortlet

Pluto

uPortal and Portlets

uPortal

Tomcat

AnnouncementsChannel

UBC Webmail

Application Server

RSS Feed

WeatherPortlet

Wrapper

SearchPortlet

Wrapper

Event Cal.Portlet

Wrapper

PlutoWeather Portlet

Search Portlet

Events Calendar Portlet

uPortal

uPortal

AnnouncementsChannel

UBC Webmail

RSS Feed

WeatherPortlet

Wrapper

SearchPortlet

Wrapper

Event Cal.Portlet

Wrapper

A Portlet in uPortal

Weather Portlet Wrapper(an instance of CPortletAdapter)

edu.duke.oit.ows.portlets.WeatherPortlet

The Portlet Pieces

Source Code portlet.xml

web.xml

web.xml

<?xml version="1.0" encoding="ISO-8859-1"?>

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/j2ee/dtds/web-app_2_2.dtd">

<web-app> <display-name>Hello World Portlet</display-name></web-app>

portlet.xml

<?xml version="1.0" encoding="UTF-8"?><portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd" version="1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_1_0.xsd"> <portlet> <portlet-name>HelloWorldPortlet</portlet-name> <portlet-class>edu.duke.oit.ows.HelloWorldPortlet</portlet-class> <expiration-cache>0</expiration-cache> <supports> <mime-type>text/html</mime-type> <portlet-mode>EDIT</portlet-mode> <portlet-mode>HELP</portlet-mode> </supports>

<portlet-info> <title>Hello World Portlet</title> </portlet-info> </portlet></portlet-app>

When changing portlet.xml

• You’ve got to restart uPortal for the changes to show up, even after a re-deployment!

• I will forget to do this at least once today

Portlet source code

• Extend GenericPortlet (or other portlet class, like JSPPortlet)

• Override one or more standard methods: doView, doEdit, doHelp, processAction

Portlet Modes

• View: The default portlet mode, providing the standard UI for the portlet

• Edit: A mode for setting user-configurable preferences

• Help: Displays help for using the portlet• Modes can be specified on a per mime-type

basis• Custom modes can be defined by the portal to

provide more modes

Window States

• NORMAL: A regular window• MAXIMIZED: A window taking up the

entire content space of the portal page• MINIMIZED: Just the title bar of the portlet• Custom window states make also be

defined by the portal• EXCLUSIVE: uPortal adds this mode to

facilitate file uploads

processAction

• The processAction method is called when the portlet receives an action. This is where any logic that the portlet provides should be tripped, including storing/updating preferences

Call sequence

do<Mode> method

processAction method (if there's an action)

init (if first time)

Portlet

Web Server / Portal Application

Request from Browser

About the init method

• It is not safe to assume that the portlet is in an active portal container until the init method is called. Therefore, make no attempt to access services from the constructor of the portlet or in any location before the init method is called

Hello World Portlet

Deploying the Portlet

• Step 1: User uPortal ant target ‘deployPortletApp’ to deploy application to the serverant deployPortletApp -DportletApp=<file>

• Step 2: Configure uPortal to see the portlet as a channelPortlet Defintion ID: warFileName.portletName

Notes about Portlet Deployment

• If you do something wrong, uPortal is likely to cache the error. Best to restart in a development environment to make sure deployment descriptors are correct

• Deployment happens just like a regular web app, except that the ant task alters the web.xml file to make it usable by uPortal

Creating an action

• First, generate an actionURL

PortletURL actionURL = response.createActionURL();

• Then, actionURL.toString() will provide the URL that will trip a processAction call.

• Parameters can be added to the actionURL (or any other PortletURL) with actionURL.setParameter(String name, String value);

Changing Modes

• VIEW / EDIT / HELP are default modes• To change modes, generate an action

URL:PortletURL actionURL = renderResponse.createActionURL();

• This calls the processAction method when followed, then, within the processAction method, set the appropriate destination mode:actionResponse.setPortletMode(PortletMode.EDIT);

Modes and uPortal buttons

• EDIT -> EDIT

• HELP -> HELP

Portlet Parameters

• Parameters can be set within the portlet.xml file so that compiles are not required to move portlets from installation to installation

• There are 2 kinds of parameters, init-params and portlet-preferences

init-param

• Initialization parameters (ie. Site dependant constants) specified in portlet.xml <init-param>

<name>defaultZipCode</name><value>27705</value>

</init-param>

• Readable from a PortletConfig object available in all init methodsString zipCode = config.getInitParameter(“defaultZipCode”);

portlet-preferences

• When defined within the portlet.xml file, these are default values for the per-user runtime preferences

• Preference values may be set as read-only

• Essentially a variable initialization mechanism for runtime user preferences

User Preferences

• Each portlet can use the portal’s data store to hold on to per-user preferences

• To read in preferences: PortletPreferences prefs = request.getPreferences();

• To read a particular named preference:prefs.getValue(String pref_name, String default);

• The above will return default if there is no preference named pref_name for that user, otherwise the value of that preference will be returned

User Preferences

• The getValue() method returns a String

• The getValues() method returns a String[]

• Preferences are read-only in all the “do” methods

• Preferences are read-write in the processAction method

User Preferences

• To store preferences:PortletPreferences prefs = actionRequest.getPreferences();prefs.setValue(“nickname”, “Matt”);prefs.store();

• Values are not committed until the store() method of PortletPreferences is called

• User preferences should not be used as a general purpose database. The intent is only to hold portlet preferences (settings)

• Use JNI or another method for getting a database handle if larger scale db operations are needed

User Attributes

• Some basic security attributes are available from the request object:request.getAuthType() <-- returns a constantrequest.getRemoteUser() <-- login IDrequest.getUserPrincipal() <-- returns user principalrequest.isUserInRole(String) <-- role (group) checkingrequest.isSecure() <-- https? (or equivalent?)

User Attributes

• Portlets can be granted access to the user attributes available in the portal framework

• In uPortal terms, these are the attributes defined in the PersonDirs.xml file

• Available attributes must be defined in the portlet.xml file (JSR-168) spec in addition to the PersonDirs.xml file (uPortal)

User Attributes

• Attribute values can be retrieved in the portlet from the USER_INFO map returnable from a renderRequest or actionRequestMap userInfo; userInfo = request.getAttribute(PortletRequest.USER_INFO);String uniqueID = userInfo.get("uniqueID");

Caching

• uPortal caches portlet content until the portlet receives and action or a render request. This means that the ‘reload’ button will not update content in portlets. Only interaction with the portlet will cause an update

• This turns out to be a useful mechanism for reducing load on external resources

• It also keeps portal response very fast

Better display options

• Keeping your (X)HTML in the portlet code is not optimal. Best practice is to separate logic from view. Some options for a better View technology: JSP JSF XSLT Spring (in beta - coming soon, example in the

CVS repository for uPortal)

Request Dispatchers

• You can use a PortletRequestDispatcher to send the PortletRequest onto another rendering service

• First obtain the request dispatcher from the portletContext:PortletRequestDispatcher rd = getPortletContext.getRequestDispatcher(“/MyPortletView.jsp”);

• Then, include the current request and response so that parameters can be seen by the .jsp (or JSF, or other rendering service):rd.include(request,response);

CSS Standards

• The JSR-168 spec lists standard CSS class names for use within portlets Adhering to these names is suggested. uPortal will most likely adopt these standards

• See Appendix C of the JSR-168 spec

Request Attributes

• Request attributes can be used to send data to JSPs or other rendering technology:request.setAttribute(“name”, “Matt”);

• In the JSP this attribute can be retrieved with:<% String name = renderRequest.getAttribute(”name"); %>

Response Properties

• Properties can be added to the PortletResponse:response.setProperty(“expiration-cache”, 0);

• The above is a useful property to set if there’s an exception thrown in the Portlet

What doesn’t uPortal implement?

• The portlet title, usually read from a parameter in portlet.xml or a resource bundle, is defined in the channel definitions

• Expiration cache has no meaning within uPortal - update: just added

• User elements accessed via a portlet must be defined both in portlet.xml and PersonDirs.xml

What does JSR-168 miss?

• Inter-portlet communication

“Trick” Inter-portlet communication

• A portlet application is a collection of individual portlets

• User the PortletSession available from a PortletRequest to transport attributes between portlets within a portlet application

Inter-portlet Communication

• Since the processAction method is guaranteed to run first, make any state changes there first:PortletSession ps = actionRequest.getPortletSession();ps.setAttribute(“zip”, zip, PortletSession.APPLICATION_SCOPE);

• The SCOPE specified in the setAttribute method allows the attribute to be seen on either the Portlet level or the Portlet Application level

Inter-portlet Communication

• Attributes can be retrieved from the session in the “do” methods of a portlet:PortletSession ps = renderRequest.getPortletSession();String zip = (String)ps.getAttribute(“zip”);

Inter-portlet Communication Caution!

• There’s no guarantee of execution sequence of doView, doEdit methods of the portlets on a portal page

• Some “do” methods may not be fired because of the caching paradigm being applied to that portlet

• There is no guarantee that a user might delete one essential part of a portlet app without removing the others, so something like Aggregated Layouts would have to be used

Resources