Harnessing JSR-168
Harnessing JSR 168Assets, Portlets, & the Portlet Container
Presented by Andrew Wills
Unicon Academus Technical Lead
Harnessing JSR-168
Portlets, uPortal, & Academus
October 2003Final Release, v. 1.0 of the Portlet Specification
April 2004uPortal v. 2.3 includes support for portlets
Fall of 2004Unicon develops Academus v. 1.5, featuring a
completely new Briefcase Portlet
Harnessing JSR-168
Scope
This presentation takes a look at creating a compelling portal based on the technology defined in the Portlet Specification v. 1.0
It examines life in the portlet container, then outlines patterns and practices geared toward flexibility, inter-operability, and success
Harnessing JSR-168
Overview
Part I: The Portlet ContractLeveraging the container to full advantage
Part II: Asset Pervasiveness©
Strategies for deeper integration
Harnessing JSR-168
Part I:The Portlet
Contract
Harnessing JSR-168
Portal, Portlet, & Portlet Container
“A portal is a web based application that – commonly – provides personalization, single sign on, [&] content aggregation […]” [PLT.2.1]
“A portlet is a Java technology based web component, managed by a portlet container […]” [PLT.2.2]
“A portlet container runs portlets and provides them with the required runtime environment.” [PLT.2.3]
Harnessing JSR-168
Significant Types
These interfaces shape your role in the container and resources available from the container
– Portlet– PortletConfig– PortletContext– PortalContext
Harnessing JSR-168
The Portlet Interface
package javax.portlet;
Public interface Portlet {
void destroy();
void init(PortletConfig config);
void processAction(ActionRequest req, ActionResponse res);
void render(RenderRequest req, RenderResponse res);
}
Harnessing JSR-168
Portlet Interface Methods
Portlet interface methods are of two kinds:
Lifecycle Management– init()– destroy()
Request Processing– processAction()– render()
Harnessing JSR-168
Lifecycle Management: Initialization
Use the init() method to establish connections to backend services, read initialization files, etc
Don’t perform these tasks in constructors or static initialization blocks. The portlet is not guaranteed to be in a valid portlet runtime until the init() method is called [PLT.5.2.2.2]
Harnessing JSR-168
PortletConfig at a Glance
“The configuration holds information about the portlet that is valid for all users.” [api PortletConfig]
• One per portlet definition
• Portlet init parameters
• Title & keywords (ResourceBundle)
• Access to the PortletContext
Harnessing JSR-168
PortletConfig Example
We used an init parameter from the PortletConfig to pass the location of a configuration file to the portlet
String settings = config.getInitParameter(SETTINGS_PATH);
This approach allowed us to define our portlet multiple times, each with a different configuration file
Harnessing JSR-168
PortletContext at a Glance
“The PortletContext interface defines a portlet’s view of the portlet application within which the portlet is running.” [PLT.10.0]
• One instance per portlet app.
• Context Init Parameters
• Context Attributes
• Access to Resources (Files)
• Request Dispatching
Harnessing JSR-168
PortletContext & ServetContext
“Context attributes set using the PortletContext must be stored in the ServletContext of the portlet application.” [PLT.10.3]
Use context attributes to share information between your portlets and servlets/JSPs in the same web application
Harnessing JSR-168
PortletContext Example
We used the PortletContext to access resources included with our portlet application
String path = context.getRealPath(settings);
It allowed us, for example, to learn the full, file system path of the configuration file indicated by the PortletConfig
Harnessing JSR-168
PortalContext at a Glance
“The PortalContext interface provides information about the portal that is invoking the portlet.” [PLT.13]
• Vendor and version information
• Portal properties
• Portlet modes & window states supported by the portal
• Available only within rendering cycles
Harnessing JSR-168
Request Processing
Request processing comes in two forms:– Action Requests
– Render Requests
To develop useful and interesting portlets, It is essential to understand the difference
Harnessing JSR-168
Request Processing
• Each client request invokes at most one action request
• Each client request may invoke any number of render requests, depending on layout, caching, and other factors
• A portlet may be rendered many times between action requests
Harnessing JSR-168
Request Processing: The Old Way
Browsers operate on the document model
Behavior & web applications have been ‘piggybacked’ or retrofitted to the web
Harnessing JSR-168
Request Processing: The New Way
The portlet contract does us a huge favor by making the distinction more formal
Unlike servlets, portlets are not bound to a logical location (URL) [PLT.3]
Harnessing JSR-168
Action vs. Rendering
Keep a sharp distinction between action-related activities and render-related activities
Avoid invoking domain behavior in rendering cycles; avoid UI-bound reads in the action cycle
Harnessing JSR-168
Action Requests
Do:– Invoke domain behavior– Change member data in domain (business)
classes– Change portlet mode, window state, and
portlet preferences
Don’t:– Process rendering logic (e.g. paging)– Read data for display
Harnessing JSR-168
Render Requests
Do:– Process rendering logic (e.g. paging)– Read data for display
Don’t:– Invoke domain behavior– Change member data in model (business)
classes– Change portlet mode, window state, and
portlet preferences
Harnessing JSR-168
The Portlet Container
Noteworthy:
• One portlet instance per portlet definition per JVM
• Zero-argument constructor for portlets
• Request & response objects may be reused – behavior of references maintained across cycles is non-deterministic
Harnessing JSR-168
Summary: The Good News
The Portlet Specification improves our lives as portal developers
– It makes our applications portable, allowing us to work with competing containers & enabling us to package our technology as plugable components
– It gives us a better, more evolved paradigm for web applications
Harnessing JSR-168
Summary: The Other Good News
The Portlet Specification is tightly scoped. It’s silent concerning topics like
– Rendering technologies & frameworks– Data access APIs– Transactional (atomic) operations– Communication between portlets, portlet
apps, and other systems
Harnessing JSR-168
The Other Good News (cont.)
This approach gives portlet developers the flexibility to choose ‘best of breed’ solutions, or those that are appropriate to the circumstances
In the context of a portal, these issues deserve special emphasis; don’t let ‘content aggregation’ begin and end with the browser window
Harnessing JSR-168
Part II:Asset
Pervasiveness
Harnessing JSR-168
What is an Asset?
An asset is a collection of related data points that represent a single logical entity
Assets are the work-product that result from the actions of users upon your system
Harnessing JSR-168
Asset Examples
The following are all assets:– Files (images, documents, &c.)– Calendar Entries– Contacts (e.g. Addressbook)– News Items & Announcements– Email Messages– Learning Objects (e.g. Content, Tests,
Class Rosters)– Objects from 3rd Party Systems (SIS, CMS,
&c.)
Harnessing JSR-168
What is Asset Pervasiveness?
Entities are created, managed, referenced, and consumed across tool (portlet) boundaries
Harnessing JSR-168
Importance of Asset Pervasiveness
A useful portal aggregates tools to work together, not simply appear together
Our experience is that application software doesn’t get adopted in discreet units. It should be bundled, inter-operative, inter-compatible, or all of the above
Harnessing JSR-168
Scenario Examples
The following are scenarios involving asset pervasiveness:– Send an email to someone in your contacts
list.– Post an image from your briefcase to a
discussion forum.– Reference (and link) a calendar entry
within an announcement.– Share a folder in your briefcase with all the
students in your class.
Harnessing JSR-168
Academus Briefcase
Harnessing JSR-168
Strategies
In the process of developing of Academus 1.5, we used the following patterns & practices to make the most of our assets
Harnessing JSR-168
Focus on Assets
Create useful, meaningful entities that are not tool-bound
Maintain an asset-centric view of your technology
Harnessing JSR-168
Assets Before Tools
Design asset behavior and structures first
Harnessing JSR-168
Design Dependencies Carefully
Import asset types from UI types, never the other way around
Harnessing JSR-168
Keep it Clean
Avoid cross-tool imports (portlet-to-portlet)
Avoid hybrid structures (part model, part UI). For example, don’t include text-formatting utility methods on your entities
Harnessing JSR-168
Design Patterns
The following patterns come in handy for designing asset-based subsystems:
• Abstract FactoryAsset subsystems may have multiple implementations. Use abstract factories to
create entities that play well together
• AdaptorUse the adaptor pattern to make open source or 3rd party features appear like your
asset subsystems to your portlets
• FaçadeAggregate the services of a complex subsystem into a single point of contact for
your portlets
Harnessing JSR-168
Singleton Pattern
Be careful using the Singleton pattern
In most circumstances, asset subsystems don’t benefit from one-per-JVM restriction
Asset pervasiveness thrives on flexibility
Harnessing JSR-168
Scalability
Design your assets for multi-server deployments– Query entities each
rendering cycle
– Plan subsystem boundaries carefully to for future implementations based on technologies like JMS & Web Services
Harnessing JSR-168
Assets in Portlets
• All users share the same portlet instance – provide a mechanism to access the appropriate assets by user or user session
• Invoke behavior in asset subsystems only in the action request cycle
• Refresh collections of assets during each request cycle – action or rendering
• When displaying asset information, read the actual asset in each rendering cycle
Harnessing JSR-168
Questions