Home
Interests
Photos
Favorites

Understanding Portals and Portlets: Part Two
A real-world implementation

By Kenneth Ramirez 

Related Links: Understanding Portals and Portlets: Part One

In the November issue of JDJ (Vol. 9, issue 11) I explained the theory behind the JSR 168 (Portlet Specification) from an academic perspective. The specification provides the infrastructure, classes, interfaces, and JSP tags for building applications that can be pieced together from a handful of off-the-shelf or custom portlets. This time around, I provide you with a real-world implementation that utilizes the knowledge you picked up from Part 1 of this series.

Along the way, you'll learn how to properly install Pluto (the Portlet Reference Implementation you can use to test your portlets) and learn about some pretty cool tools as well.

A Quick Refresher
Last month, we learned that portlets are similar to servlets, except they aren't allowed to use several HTML control tags such as the <body> tag. This is because the portal page provides these controlling tags, whereas the portlets provide the tags necessary to complete their own work.

Portlets also share the application context with servlets and JSPs and can even include the output of another servlet or JSP as part of their content. To offer the user the ability to customize portlets, there are special Window States (such as normal, minimized, and maximized) and Portlet Modes (such as Edit, View, Help) that can be controlled by the end user. Furthermore, the portlet can use these states and modes to determine what content it needs to show the user at any given point. User's actions are received within a portlet in the form of both action and render methods. Action methods respond to the user's interaction with the portlet, and render methods are called to paint the output of the portlet.

Later in this article, we'll see how we can put all of these features and settings to use in our example portlet. However, before we can dive into the code, we need to ensure that our environment is ready to test a portal page and its contained portlets.

Required Downloads
Given the fact that Pluto is very Mavenized these days, you'll need to download Maven (a tool that allows you to build and deploy your project based on a Project file). In addition, you'll need a servlet engine to run Pluto (since Pluto runs as a servlet). I suggest Tomcat (preferably version 5) as the servlet engine.

If you're developing on a Windows machine, the Tomcat setup is pretty easy. I downloaded Tomcat from the Apache Web site using http://jakarta.apache.org/tomcat/.

Make sure you extract the Tomcat binaries into its own directory and be sure you have the JAVA_HOME environment variable pointing to your Java installation directory path. Once Tomcat is installed, try your hand at Maven. Download and install Maven from the Apache Web site as well.

Define an environment variable named MAVEN_HOME and point it to the Maven root directory. You may also want to add Maven's bin directory to your path, so you can easily execute Maven from any command prompt window in any directory. If all goes well, you should be able to run Maven with the -v option to view its version information.

Finally, it's time to locate and download Pluto. At the time of this writing, the latest version of Pluto is 1.0.1, and is in a Subversion Source Code Management (SCM) system. If you visit http://cvs.apache.org/viewcvs.cgi/portals/pluto/trunk/?root=Apache-SVN, you'll find the trunk.

You can either use the Web interface to surf each package and download them directly (which is very cumbersome), or you can download and use Tortoise for Subversion, which adds context options to Windows Explorer in order to assist you in downloading content from various Subversion repositories across the Internet. The Tortoise installation and documentation is located at http://tortoisesvn.tigris.org.

Tortoise provided Windows Explorer with new context menu items as shown in Figure 1.

Next, you'll need to create a new directory and download Pluto. Right-click in the newly created directory while in Windows Explorer to bring up the context menu and select the option marked "Checkout...". You'll need to specify the complete path to the Subversion repository, which is mentioned on the Apache.org Web site as follows http://svn.apache.org/repos/asf/.

A Subversion repository is similar to CVS, but provides added features and is becoming extremely popular. Many sites are changing their repositories from CVS to Subversion (and the Apache group is no exception).

I simply added the remainder of the URL to locate the Pluto project as shown in Figure 2.

Once you download Pluto's source files you'll have a complete directory tree with the necessary files needed to build Pluto. You can always update Pluto with newer changes by opening the context menu offered by Tortoise. You'll notice that the menu will change to reflect new choices available now that you have downloaded Pluto.

To run Maven against the Pluto file, you'll need to perform the following tasks:

1. Copy the build.properties.sample file to build.properties.
2. Modify the build.properties and specify the location and version of Tomcat:

maven.tomcat.home=/tomcat-5.0.27
maven.tomcat.version.major=5

3. Run the maven fullDeployment command.

The fullDeployment operand tells Maven to run this task within the project file. The task has been provided with everything needed to download any necessary or missing projects, compile Pluto, and deploy Pluto.

Now, you're ready to access Pluto for the first time (it comes with a test portal). First, you'll need to run Tomcat. Once Tomcat has finished loading, you can access the portal by surfing over to http://localhost:8080/pluto/portal. You should be presented with the page shown in Figure 3.

If you click on the Test portal, you'll be able to test out much of what a JSR 168 portlet has to offer. You'll see two instances of the same portlet host on a portal page with two columns (one for each portlet). The source code can be located at [pluto-installation-dir]/testsuite.

The ImageViewer Portlet
When I thought about writing the example for this article, I wanted to come up with an idea that was simple enough to understand, yet realistic enough to give you a starting point for building your own real-world portlets. (The source code for this article can be downloaded from www.sys-con.com/java/sourcec.cfm.) The result is a portlet that utilizes many JSR 168 features to provide an end user with a portlet that has two portlet modes: view and edit.

The view mode allows the end user to specify an image stored in a subdirectory named images on the server side (relative to the portlet's context root), and displays the image within the portlet on the way back to the browser. After entering a name and clicking the "Show Image" button, the user is presented with the result as illustrated in Figure 4.

You'll notice that there is some text in the portlet that specifies, "color = white". White is the default color chosen for the portlet's background. However, this can be changed by entering the Edit mode of the portlet, which is achieved by clicking on the "edit" link on the portlet's title bar. When you do so, you're presented with the output shown in Figure 5.

If you change the selection to "Blue" and press the "Change Color" button, then go back to View mode and select an image, you'll notice that the background now reflects the new background color.

The ImageViewer Source Code Explained
Now that you've seen the ImageViewer portlet from the end-user's perspective, let's take an in-depth look at the source code.

The first thing I did was to set up my directory structure, which resembles the image shown in Figure 6.

I knew that I would be building the files listed in Table 1.

The Portlet.XML Deployment Descriptor File
Let's look at the portlet.xml file, which contains the various descriptors used to deploy the portlet properly (see Listing 1).

The first part of the file includes the standard customary XML tag used to identify the file and the schema used to validate the file's content. Next, we see the root portlet tag. Within this tag are several other tags including description, portlet-name, display-name, portlet-class, init-param (of which there are three), supports (for mime types), locale, and portlet-info. The most important of these tags are the portlet-name and the portlet-class tags.

The portlet-name provides a name that can be used internally or programmatically to reference the portlet, while the portlet class provides the classpath used by the portlet container to load the appropriate class and create instances from it.

The description tag can be used by development tools to provide a description of what the portlet does, whereas the display name can be used to provide the developer with a unique name that (hopefully) differs from other portlets in the portlet catalog. As portals become more popular, you'll start to see drag-and-drop support within the various development environments, allowing developers to drag portlets onto a portal page and drop them into the page. The display name will become very important, showing the developer which space is occupied by which portlet.

I included three different init-param values that provide the portlet with the names of the JSPs used for its View and Edit modes and the default background color of white.

The supports tag provides the mime-type tag, which tells the portlet container that the portlet will provide HTML for the various views and that two different modes are supported: View and Edit. The supported locale tag specifies that our chosen language is English.

Finally, the deployment descriptors provide the title tag, used by default for providing a title for the portlet in the portal page; the short title, which can be used to provide a shorter version of the title (for use in WAPs or other devices that have a smaller screen display area); and keywords, which are used to search for portlets within development tools. The search can, for example, narrow down the catalog of portlets to a few portlets that support stock screening or image manipulation, or whatever other functionality you're interesting in providing your end users with from your portal pages.

The ImageViewerPortlet Java Source File
The source code for the ImageViewerPortlet.java file starts off by defining the package name and importing the necessary packages and/or classes. Next, it names the class and provides the methods. There are no data members in this class (see Listing 2).

The first method we'll look at is init(). This method doesn't have much to do in this case, but I wanted to assure you that it is in fact called. Therefore, I simply added an output message to the console.

Now it's time to meet the processAction() method. Based on the retrieved portlet mode, the portlet determines whether it's in View mode or Edit mode. If it is in View mode, this method simply has to copy the present parameters (passed from the user's browser, which includes the image name the user wishes to see) into the response's render parameters so they can be picked up by the doView() method. If the portlet is in Edit mode, it retrieves the current background color from the request (this is always passed in the JSP as you'll soon see), and places it in the PortletSession (where it can be picked up by the JSP page). I could have used portlet preferences for the background color (along with a validator class), but I chose to keep the example simple.

Next, we come to the doView() method. This method retrieves the PortletSession object, which can be used to then retrieve the bgColor. This is just one of many ways to pass data around. I simply wanted to use as many techniques as possible without overwhelming you.

If the background color has not been set into the session, it's set at this point by retrieving the default color from the portlet's configuration object using the getInitParameter() method.

Next, I set the mime type for the view mode and dispatch to the JSP page (including its output in the final HTML sent to the browser).

Finally, the doEdit() method appears in the listing. This one is pretty simple and resembles the bottom half of the doView() method. The only difference is that it dispatches to the Edit JSP instead of the View JSP.

The View JSP
The view.jsp file provides the source code in Listing 3. The top portion of this file includes the portlet tag library. One of the most important steps you must take (before you can use any of the portlet internal objects) is to call portlet:defineObjects tag, which is provided by the tag library. Next, it creates a few variables to hold the action URL, the image filename the user specified, and the background color (retrieved from the session object).

After creating the variables, the HTML provides a string containing the current color, a form to include the controls used by the user to interact with the portlet, and the submit button.

If a filename is provided, the name is used with some special methods to conjure up a complete path to the actual image file. You must use the renderRequest.getContextPath() method to create a legitimate path. Don't assume that you could simply use the relative path and it will work.

Finally, the newly created path is used in the image tag to display the image within the portlet.

The Edit JSP
The code for the Edit JSP isn't much different from that of the View JSP. It only differs in its content, which should be very self-evident (if you know HTML at least at a basic level). See Listing 4 to view the source code for the edit.jsp file.

Deploying to Pluto
To build the source code, I created an Ant file. Once you have compiled the code, you can deploy it to the Pluto portal using the following commands:

cd\jakarta-pluto
maven deploy -Ddeploy=/ImageViewer/target/ImageViewer.war

There are still a few more steps you have to follow in order to view the portlet within Pluto. You need to modify the Portlet Entity Registry and the Page Registry files. These can be located at:

[tomcat-home]/webapps/pluto/data/portletentityregistry.xml
[tomcat-home]/webapps/pluto/data/pageregistry.xml

The portlet entity registry file requires that you specify an application and a portlet ID for your new portlet. The application ID must be unique. The portlet entity registry file also needs to know the name of the portlet so that it can go out and find it in the webapps path. Furthermore, this information is used to map the portlet name to the appropriate classpath for loading the class. The following are my additions to the portlet entity registry file:

<application id="6">
<definition-id>ImageViewer</definition-id>
<portlet id="1">
<definition-id>ImageViewer.ImageViewerPortlet</definition-id>
</portlet>
</application>

The page registry provides Pluto with the layout information for your portlet. The names used in the fragments must be unique as in my example:

<fragment name="ImageViewerPortlet" type="page">
<navigation>
<title>ImageViewer Portlet</title>
<description>...</description>
</navigation>

<fragment name="row3" type="row">
<fragment name="col3" type="column">
<fragment name="p4" type="portlet">
<property name="portlet" value="6.1"/>
</fragment>
</fragment>
</fragment>

In the above example, I simply told Pluto that I will need one row by one column. Within that row/column, I want it to display the portlet identified by "6.1". The number "6" is the application ID and "1" is the portlet ID.

After you edit and save the two XML files, restart Tomcat and you should now see the Portal page link named "Image Viewer".

Summary
Although I've tried to provide you with as much information and features as I could, the only true way to learn how to build the JSR 168 portlets is to jump right in and do it. You should be able to use this code as the foundation for other portlets. Remember, if you do decide to start creating portlets, try to make them self-contained units of work. That way, they can be shared across projects, teams, and possibly even companies.

Copyright 1994-2005 SYS-CON Publications, Inc.

Questions or problems regarding this web site should be directed to abeckman@outdoorssite.com.

Copyright 2008 Art Beckman. All rights reserved.

Last Modified: March 9, 2008