04 Working with Portlets in uPortal
Guide to Working with Portlets in uPortal
Contents
- Introduction
- Servlet Container Issues
- Sample Portlets
- Deploying Portlets
- Publishing Portlets
- Portlet Caching
- User Information
- Portlet Security
- Custom Portlet Modes and Window States
- Future of Portlets in uPortal
Introduction
uPortal is committed to supporting open standards including the Java Portlet Specification, initially known as JSR 168. Portlets are designed to be the basic building block of a Portal. The uPortal analog to a Portlet has thus far been the Channel which is based on the org.jasig.portal.IChannel java interface. To provide a runtime environment for Portlets, uPortal has chosen to use a Portlet Container from the Apache Jakarta project called Pluto. Pluto is the reference implementation of the Java Portlet Specification. Beginning with uPortal 2.3, uPortal embeds the Pluto container and includes a Portlet adapter that makes it possible to install and render Portlets along with its native Channels. The End-User of uPortal can not tell the difference between a Portlet and a Channel.
Pluto, when downloaded separately from Apache, is distributed with several components:
- Portlet API (JSR-168)
- Portlet Container
- Portal Driver
- Test Suite Portlet
uPortal includes the Portlet API, Portlet Container, and Test Suite Portlet, but not Pluto's Portal Driver which is not meant to be a fully functional portal. uPortal acts as the Portal Driver. This guide gives you an overview of the uPortal Portlet environment.
Servlet Container Issues
uPortal, with its implementation of Pluto, requires that the web application context representing the deployed portal web application be set as "cross context" because Pluto dispatches the Portlet request objects to the individual Portlet applications which run in their own web application context. Each servlet container should provide a means to enable this "cross context" setting. It can be accomplished in the Tomcat servlet container in the following ways:
- For Tomcat 5, you can include an XML file in the conf/Catalina/{hostname} directory that contains the <Context> element definition. uPortal 2.3 automatically deploys such a file properties/uPortal.xml to conf/Catalina/localhost/uPortal.xml. This, of course, assumes that your context name is uPortal and your hostname is localhost.
- For Tomcat 4, you can include a similar XML file in the webapps directory.
- For either Tomcat 4 or 5, you can alternatively edit the conf/server.xml file, adding a <Context> element for your portal application with the crossContext attribute set to true:
<Context path="/uPortal" docBase="uPortal" crossContext="true"> </Context>
Note: uPortal will not be able to run Portlets in Tomcat 5.0.19 because of a Tomcat bug that is documented here.
Sample Portlets
uPortal comes with 3 sample Portlets that are preinstalled:
1. Test Suite Portlet - comes with Pluto Info
2. RSS Portlet - comes from Portlet Open Source Trading Site (POST) Download
3. Google Portlet - comes from Portlet Open Source Trading Site (POST) Download
To use these Portlets, log into uPortal with user name and password demo/demo and navigate to the tab called Portlet Examples. You should see 2 instances of the Test Suite Portlet in the first and second columns and the RSS and Google Portlets in the third column. The Test Suite Portlet tests the Portal Driver's implementation of the Portlet Container. The RSS Portlet and Google Portlet are just Portlet examples and were contributed to POST by Plumtree Software.
Note: The Google Portlet will not be fully functional until you configure a license key in the <init-param> element of Google Portlet's portlet.xml file. To obtain a license key, visit Google Web APIs and follow instructions to set up an account. Once you have the license key, unzip the GooglePortlet.war file, modify the WEB-INF/portlet.xml file, and then zip it all up again.
Deploying Portlets
The sample portlets mentioned above were all deployed as part of uPortal's initportal ant target. The ant target subtask of initportal that performs the deployment of Portlet Applications is deployPortletApp. The deployPortletApp target runs the portlet deployer tool, org.jasig.portal.container.deploy.Deployer. This tool takes a Portlet WAR file, rewrites the web.xml file (a requirement of the Pluto Portlet Container), and deploys the results to the servlet container. You can deploy multiple portlets at once by placing them in uPortal's lib/portlets directory and specifying all as the porletApp. For example:
ant deployPortletApp -DportletApp=all
You can also deploy one Portlet application at a time by specifying the location of the Portlet application WAR file:
ant deployPortletApp -DportletApp=C:/TEMP/myPortlet.war
Publishing Portlets
uPortal will build a Portlet Registry based on all the Portlets that are deployed into the servlet container. It does this by examining all the installed web applications, looking for the ones that contain a portlet.xml file, and parsing that portlet.xml file to find out what Portlet Application Definitions and Portlet Defiinitions are available.
To publish a Portlet in uPortal, you need to know the Portlet Definition ID and any necessary parameters. The Portlet Definition ID is in the form of [UPC:portlet-context-name].[UPC:portlet-name]. For example, for the Pluto Test Suite Portlet, the application was bundled as testsuite.war and the Portlet name from portal.xml was TestPortlet1. Therefore the Portlet Definition ID for this Portlet would be testsuite.TestPortlet1.
Once you know the Portlet Definition ID, you can publish the Portlet either via the Channel Manager publishing GUI or by creating a channel definition XML file and placing it in uPortal's properties/chanpub directory. That directory already contains sample channel definition XML files for the 3 included sample Portlets that are described above. If you choose to publish the Portlet using the GUI, select the Portlet channel type and follow instructions to enter the required parameters. In both cases, you are actually publishing a Portlet adapter which knows how to find and render the appropriate Portlet based on the Portlet Definition ID.
Portlet Caching
In order to make the Portlet adapter as efficient as possible, a caching strategy was implemented that is beyond the scope of the Portlet's control. It works as follows: uPortal will cache the contents of a Portlet screen until one of the following occurs:
- The user clicks on a link or button within the Portlet.
- The user clicks on a button within the Portlet control bar, i.e. Edit, Help, About, etc.
- The Portlet is focused or unfocused, i.e. the Portlet alternates between being the root of the layout and not the root of the layout.
- A PortalEvent is sent to the Portlet.
When one of these activities occurs, it usually triggers a state change within the Portlet, and the new screen is cached until one of these activities happens again. Therefore, simply clicking refresh on your browser will not cause the Portlet to render itself again. The optional Portlet caching settings mentioned in the Portlet Specification are not implemented at this time.
User Information
As of uPortal 2.3.2, you will be able to access a user attribute with the following code:
Map userInfo = (Map)request.getAttribute(PortletRequest.USER_INFO); String givenName = (String)userInfo.get("user.name.given"); String lastName = (String)userInfo.get("user.name.last");
The Portlet Specification says that you should be able to map user attribute names declared in the portlet.xml file at deployment time. In uPortal, this feature will not be available. Instead, you will have to edit uPortal's PersonDirs.xml file, adding aliases for any of the user attribute names declared in the portlet.xml file that don't already exist in PersonDirs.xml. Only the attributes defined in portlet.xml will be accessible to your portlet. For example, if your portlet.xml file contains...
<user-attribute> <description>User Given Name</description> <name>user.name.given</name> </user-attribute>
...then your PersonDirs.xml will need to contain something like...
<attribute> <name>FIRST_NAME</name> <alias>user.name.given</alias> </attribute>
As of uPortal 2.4, Portlets can be configured to receive the user's password as a user attribute. If this is desired, simply include the following user attribute mapping in portlet.xml:
<user-attribute> <description>User Password</description> <name>password</name> </user-attribute>
If a password mapping was specified in PersonDirs.xml, then it will be used. Otherwise, uPortal will look for the password in the user's authenticated security contexts that cache credentials, using the first one it finds.
Full support of deployment-time mapping will be available in uPortal 3.0.
Portlet Security
As of uPortal 2.4, Portlets in uPortal can make use of the getRemoteUser(), getUserPrincipal(), and isUserInRole() methods of the PortletRequest.
Each method will first try to call its respective method on the original servlet request to see if the information is available (it would be available if J2EE security was properly set up in the container and the container has authenticated the user). If not, then it will use uPortal's IPerson object in conjunction with uPortal's GroupService to determine the answers. The role mapping that must be included with the portlet.xml will be a mapping from some made-up role to a uPortal Groups key. For example:
<security-role-ref> <role-name>myEveryoneRole</role-name> <role-link>local.0</role-link> </security-role-ref> <security-role-ref> <role-name>myStudentRole</role-name> <role-link>pags.students</role-link> </security-role-ref>
If these example mappings were included and the user was authenticated and in the pags.students role, then a call from within the Portlet to portletRequest.isUserInRole("myStudentRole") and portletRequest.isUserInRole("pags.students") should return true.
Note that security tests included with Pluto's testsuite Portlet test for a role mapped to the role link of tomcat which isn't a valid role within uPortal. Therefore, some of these tests will fail until Pluto makes their tests more flexible by providing a properties file that lets us specify the role link ourselves.
Custom Portlet Modes and Window States
uPortal supports the following Portlet modes:
- VIEW
- EDIT
- HELP
When a user clicks on one of these buttons in the channel control bar, the Portlet mode will change. There is currently no button provided to switch the mode back to the default VIEW mode. At this time, custom Portlet modes are not supported.
uPortal supports the following Portlet window states:
- NORMAL - Portlet is rendered along with other Portlets in the layout.
- MAXIMIZED - Same as uPortal focused concept.
- MINIMIZED - Same as uPortal minimized concept.
- EXCLUSIVE - Gives Portlet full control over request and response. Can be used to achieve file downloading.
Future of Portlets in uPortal
uPortal 3.0 will continue to support Portlets using the Pluto Portlet Container. The Portlet will eventually replace the Channel as the primary portal module. This means that terminology within uPortal will change to reflect the use of Portlets rather than Channels. Also the rendering architecture of uPortal will be simplified to handle the Portlet natively, rather than through an adapter. The Channel, of course, will still be supported though a Channel adapter. uPortal 3.0 is still in its early design stages. More will be added to this section as the design matures.