Portlet
Applications
Thomas F.
Boehme
The
definition of web applications has brought the deployment of servlets and their
resources to a new level of ease-of-use. This document aims to establish a
similar structure for portlet applications, which should ultimately lead to
simplified deployment of portlet applications. In fact, most of the
specification in here has been directly taken from the Servlet API
specification, verison 2.3.
A portlet
application is a collection of portlets, html pages, classes, images, and other
resources that can be bundled and run on multiple containers from multiple
vendors.
The portlet
container must enforce a one to one correspondence between a portlet
application and a PortletContext. Therefore, all portlets of the same portlet
application share the same PortletContext object. A PortletContext
object can be viewed as
a portlet’s view onto its application.
A
portlet application may consist of the following items:
· Portlets
· JavaServer Pages
· Utility Classes
· Static documents (HTLM, WML, images, sounds, etc.)
·
Client
side applets, beans, and classes
·
Descriptive
meta information which ties all of the above elements together.
This
specification defines a hierarchical structure which can exist in an open file
system, an archive file, or some other form for deployment purposes. It is recommended, but not required, that portlet
containers support this structure as a runtime representation.
A portlet
application exists as a structured hierarchy of directories. The root of this
hierarchy serves as a document root for serving files that are part of this
context.
A special
directory exists within the application hierarchy named “PORTLET-INF”. This directory contains all
things related to the application that aren’t in the document root of the
application. It is important to note that the PORTLET-INF
node is not part of the
public document tree of the application. No file contained in the PORTLET-INF
directory may be served
directly to a client.
The
contents of the PORTLET-INF directory are:
·
/PORTLET-INF/portlet.xml
deployment descriptor
·
/PORTLET-INF/classes/*
directory for portlet and utility classes. The classes in this directory are used by the application class loader to
load classes from.
·
/PORTLET-INF/lib/*.jar
area for Java ARchive files which contain portlets, beans, and other utility
classes useful to the portlet application. All such archive files are used by the
portlet application class loader to load classes from.
The portlet
application classloader loads classes first from the PORTLET-INF/classes
directory and then from library JARs in the PORTLET-INF/lib directory. For the
latter case, the classloader should attempt to load from library JARs in the
same order that they appear as PAR archive entries.
Once the
portlet application’s classes are exhausted the portlet application loader
should attempt to load container-wide classes from directories or JARs.
Illustrated
here is a listing of all the files in a sample portlet application:
/monthly.jsp
/weekly.jsp
/images/readNews.gif
/images/newNews.gif
/PORTLET-INF/portlet.xml
/PORTLET-INF/lib/jspbean.jar
/PORTLET-INF/classes/com/yourco/portlets/MailPortlet.class
/PORTLET-INF/classes/com/yourco/portlets/CalendarPortlet.class
/PORTLET-INF/classes/com/yourco/util/MyUtils.class
Portlet applications can
be packaged and signed, using the standard Java Archive tools, into a Portlet
ARchive format (PAR) file. For example, an application of PIM portlets could be
distributed in an archive with the filename pim.par. When packaged into such a form, a
META-INF directory will be present which contains information useful to the
Java Archive tools. If this directory is present, the portlet container must
not allow it be served as content to a client’s request.
The
classloader that a container uses to load a portlet in a PAR must not allow the
PAR to override JDK or PortletAPI classes, and is recommended not to allow
portlets in the PAR visibility of the portlet containers implementation
classes.
If a
portlet container has a mechanism for exposing container-wide library JARs to
application classloaders, it is recommended that the application classloader be
implemented in such a way that classes packaged within the PAR are able to
override classes residing in container-wide library JARs.
Applications
evolve and must occasionally be replaced. In a long running server it is ideal
to be able to load a new portlet application and shut down the old one without
restarting the container. When an application is replaced, a container should
provide a robust approach to preserving session data within that application.
The
deployment descriptor conveys the elements and configuration information of a
web application between Developers, Assemblers, and Deployers. This chapter
defines and describes the deployment descriptor for this version.
The
following types of configuration and deployment information exist in the
portlet application deployment descriptor:
·
PortletContext
Parameters
·
Portlet
Parameters
·
Supported
Locales and Modes
See the DTD
comments for further description of these elements.
In this
section is a listing of some general rules that web containers and developers
must note concerning processing of the deployment descriptor for a web
application
·
Portlet
containers should ignore all leading whitespace characters before the first
non-writespace character, and all trailing whitespace characters after the last
non-whitespace character for PCDATA within text nodes of a deployment
descriptor.
·
Portlet
containers and tools that manipulate portlet applications have a wide range of
options in checking the validity of a PAR. This includes
checking the validity of the deployment descriptor document held within. It is recommended, but not required,
that portlet containers and tools validate deployment descriptors against the
DTD document for structural correctness. Additionally it
is recommended that they provide a level of semantic checking, for example, that
a role referenced in a security constraint has the same name as one of the
security roles defined in the deployment descriptor. In cases of non-conformant portlet
applications, tools and containers should inform the developer with descriptive
error messages. High end application server vendors are encouraged to supply
this kind of validity checking in the form of a tool separate from the
container.
·
URI
paths specified in the deployment descriptor are assumed to be in URL-decoded
form.
·
Containers
must attempt to canonicalize paths in the deployment descriptor. For example,
paths of the form ‘/a/..b’ must be interpreted as ‘/a’. Paths beginning or
resolving to paths that begin with ‘..’ are not valid paths in the deployment
descriptor.
·
URI
paths referring to a resource relative to the root of the PAR, or a path
mapping relative to the root of the WAR, unless otherwise specified, should
begin with a leading ‘/’.
Do we
need/want this at this stage?
Groups of applications
commonly make use of the code or resources contained in a library file or files
installed container-wide in current implementations of portlet containers. The
application developer needs to be able to know what extensions are installed on
a portlet container for portability, and in creating a portlet application that
may depend on such libraries, containers need to know what dependencies on such
libraries Portlets in a PAR may have.
Portlet containers are
recommended to have a mechanism by which they can expose to the application
classloaders of every portlet application therein extra JAR files containing
resources and code. It is recommended that they provide a user-friendly way of
editing and configuring these library files or extensions, and that they expose
information about what extensions are available to portlet applications
deployed on the portlet container. Application developers that depend on the
installation of library JARs installed on a portlet container should provide a
META-INF/MANIFEST.MF entry in the PAR file listing the extensions that the PAR
depends upon. The format of the manifest entry follows the standard JAR
manifest format. In expressing dependencies on extensions installed on the
portlet container, the manifest entry should follow the specification for
standard extensions defined at http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html.
Portlet
containers should be able to recognize such declared dependencies as expressed
in the optional manifest entry in a PAR file, or in the manifest entry of any
of the library JARs under the PORTLET-INF/lib entry in a PAR. If a portlet
container is not able to satisfy the dependencies that a PAR has on a
particular extension declared in this manner, it should reject the application
with an informative error message.
Do we
want/need this at this stage?
Java 2
Platform Enterprise Edition defines a naming environment that allows
applications to easily access resources and external information without the
explicit knowledge of how the external information is named or organized.
Provision
has been made in the portlet application deployment descriptor for specifying
information allowing a portlet to obtain references to resources and enterprise
beans. The deployment elements that contain this information are:
·
env-entry
·
ejb-ref
·
resource-ref
The env-entry
element contains
information to set up basic environment entry names relative to the java:comp/env
context, the expected
Java type of the environment entry value (the type of object returned from the
JNDI lookup method), and an optional environment entry value. The ejb-ref
element contains the
information needed to allow a portlet to locate the home interfaces of a
enterprise bean. The resource-ref element contains the information
needed to set up a resource factory.
The
requirements of the J2EE environment with regards to setting up the environment
are described in Chapter 5 of the Java 2 Platform Enterprise Edition v 1.3
Specification . Portlet
container implementations are encouraged, but not required, to implement the
application environment functionality described in the J2EE specification. If
they do not implement the facilities required to support this environment, upon
deploying an application that relies on them, the container should provide a
warning.
All valid
portlet application deployment descriptors must contain the following DOCTYPE
declaration:
<!DOCTYPE portlet-app PUBLIC "-//Apache//DTD Portlet Application
x.x//EN"
"http://<whatever>.dtd">
The DTD that follows
defines the XML grammar for a portlet application deployment descriptor.
DTD needs to go here. I figure that starting out with samples better conveys a possible structures of the deployment descriptor. The DTD has to be derided later.
The
following examples illustrate the usage of the definitions listed above DTD.
<!DOCTYPE portlet-app PUBLIC "-//Apache//DTD Portlet Application
x.x//EN"
"http://<whatever>.dtd">
<portlet-app>
<portlet-app-name>A PIM
Application</portlet-app-name>
<context-param>
<param-name>Webmaster</param-name>
<param-value>webmaster@yourco.com</param-value>
</context-param>
<portlet>
<portlet-name>YourCo.
Mail</portlet-name>
<portlet-class>com.yourco.portlets.MailPortlet</portlet-class>
<allows>
<minimize/>
<maximize/>
<close/>
</allows>
<supports>
<default
document=’yes’/>
<personalize
fragment=’yes’/>
</supports>
<config-param>
<param-name>default_max_items</param-name>
<param-value>5</param-value>
<param-name>default_sort</param-name>
<param-value>date,
desc</param-value>
</config-param>
</portlet>
<portlet>
<portlet-name>YourCo.
Calendar</portlet-name>
<portlet-class>com.yourco.portlets.CalendarPortlet</portlet-class>
<title>Your Personal
Calendar</title>
<title
mime-type=’application/vnd.wap.wml’>Calendar</title>
<keywords>calendar,date,appointment</keywords>
<language locale=’de’>
<title>Ihr Persönlicher
Kalender</title>
<title
mime-type=’application/vnd.wap.wml’>Kalender</title>
<keywords>Kalendar,Datum,Verabredung,Termin</keywords>
</language>
<supports>
<default fragment=’yes’/>
<personalize
fragment=’yes’ mime-type=’text/html’/>
<help fragment=’yes’/>
</supports>
<config-param>
<param-name>default_view</param-name>
<param-value>month</param-value>
</config-param>
</portlet>
</portlet-app>