With the increased popularity of portals on the Web, and organizations continuing to choose IBM ® WebSphere® Portal as their primary platform, we as a community need to quickly develop a set of reusable assets and work products that allow us to effectively design and develop portal applications. Architects and developers alike are struggling with design issues surrounding building applications to best take advantage of the framework WebSphere Portal provides.
I have often thought that what is needed is a series of models or patterns for describing portlets and their use in applications. This article articulates one approach for designing portals and portlets using the Unified Modeling Language (UML). Using basic portal design practices and UML, I provide a design framework for a simple Portlet-MVC design upon which you can build your own portlet applications. Hopefully this can be the start of a set of models for portlet designs upon which we can begin to build a set of patterns for reuse.
This article is not about coding portlets. While I present code samples which help to illustrate the UML model and design, most of the code has been stripped down to the bare essentials to focus on the design itself. Any robust application will require much more error checking and exception handling than is provided here.
Why model Portal applications?
Why should we model Portal Applications? It's actually a good question. Usually we think of a portal as a group of small, discreet pieces of functionality or content. I don't need to go to all the trouble of modeling those, do I? The marketing hype tells us that building portlets are easy, with simple portlets being built in a few hours to a few days. If this is the case, we hardly need to invest the time for a major requirement and design phase, do we? Well actually, yes! If it is really the case that a portal requires only one or two portlets that provides some discreet functionality, or access to a legacy system, then it is probably not necessary for a large upfront investment in time and people to do a complete design. A few days, to a week of design time would probably be sufficient. Or perhaps you could consider another approach, such as using an evolved prototype or extreme programming.
Unfortunately while the WebSphere Portal framework does greatly reduce our design and development time, and provides us with an extensible set of functionality, it is no silver bullet. Most major portal applications require more than a simple portlet or two. At minimum there will be a "set" of portlets or even several sets, providing the required functionality. Additionally you need utility classes, singletons, tag libraries and services that provide underlying access to a wide variety of services and systems. And let's not forget EJBs for high volume transactional systems. Larger systems of this nature require a dedicated design cycle following a proven design methodology. The one proposed in this article using UML is still evolving, even as WebSphere Portal itself continues to evolve.
The scenario presented here is quite simple. I will describe and model a simple portlet that provides basic CRUD (Create, Read, Update, Delete) functionality for a given problem. The approach taken is pretty generic. It is designed to show the basics of how a system of this type could be modeled using UML, and not to overwhelm you with examples of functionality. Most architects and designers will encounter dozens of examples of this type of portlet functionality during their career, and should be able to easily extend the ideas presented here to reflect a real world scenario.
With that in mind, we can pretend to operate on a simple object of type "Item", or perhaps a list of "Items". What "Item" actually is we aren't really interested in. It can be a set of users, customers, accounts, houses, computers, or whatever.
Gathering requirements using use cases can be tricky. They can only be done well by people experienced in use case Modeling. Generally, technical people who understand UML and use-case modeling have trouble looking at a use case from the user point of view. They are always trying to design the system at the same time as requirements are being gathered. Non-technical folks such as consultants and business analysts who understand how to build effective use cases are very rare and worth their weight in gold. These people can talk the customer's language and build effective use cases that truly reflect the business requirements.
CRUD functionality isn't always at the top of the list when it comes to design. Usually it is basic table maintenance that doesn't have a major impact on the application, so it doesn't appear to add a lot of value to the actor and is not often considered a primary use case. I believe, however, that it is one of the most common types of functionality that you will encounter and is fairly easy to understand. Being familiar with the requirements will help you not to get bogged down in the requirement details and allow you to focus on the model and the design approach.
Trying to achieve the right level of granularity for use cases can also be an issue. In a very coarse-grained system we could create one use case named "Manage Item". This is probably a little too simple for any useful analysis. It might be better to decompose this into a more complete set of use cases. To illustrate our sample portlet I have created a simple package named "ManageItems" which includes the following four uses cases:
- Search Items: Search for an item or a list of items.
- Adds Item: Add a new item to our application.
- Delete Item: Delete an item from our application. Usually performed after a search.
- Edit Item: Edit an item in our application. Usually performed after a search.
Figure 1 illustrates these use cases using a use case diagram. The actor provided here is a simple user who interacts on all four of the cases. I've also provided some additional detail such as a login case that is included by all other use cases. I haven't provided much detail for the sample use cases; they are pretty self-explanatory in what functionality they describe.
Figure 1. Use cases

The next step is to flush out each of the use cases and begin to further model the system. You can identify nouns and verbs based on the gathered functionality, and design interaction and activity diagrams. For our example we will only follow one of the cases and examine it in detail. We begin with the Search Items use case. Since all the cases are already present in the model, we can return to this view after we finish with the Search Items case and continue to model the next use case.
Activity and interaction diagrams
Activity between the user and the system can be described in several ways. Figure 2 shows an activity diagram of the SearchItems use case. This diagram is presented from the viewpoint of a user interacting with the system. This simple diagram, also known as a "swim lane" diagram, is a start to identifying components within the system. In this diagram we are viewing System as a single component. Further decomposition lets us start identifying additional objects that can be modeled into classes, and other objects within the design.
Figure 2. Activity diagram with swim lanes

Further interaction with the system either through interaction diagrams or collaboration diagrams can be used to expand the design and help derive additional objects and interactions (nouns and verbs) that are used in the model. Modeling and decomposition of this type require a solid background and understanding of UML and its use. This article only attempts to put UML into a proper context for designing portlets.
Fortunately we are building a WebSphere Portal portlet. Because of this, and the framework that WebSphere Portal provides, it is pretty easy to derive a component layout for the final portlet. We need to be smart in our design and ensure that it is taking full advantage of the framework correctly. But the portlet design can also build upon the effort of other excellent designers and follow the published API for WebSphere Portal.
To lay out the classes necessary for our portlet we can follow the basic Model-View-Controller pattern that is recommended by the framework. Figure 3 shows the basic class diagram for the Manage Items portlet. The classes in Figure 3 provide a basic layout for this and a lot of the other portlets that you may encounter when building your own portal applications. The Manage Items portlet configured in this manner can incorporate all of the use cases that were entered into the use case diagram described earlier.
Figure 3. Portlet class diagram

The initial diagram provides for three primary classes. Let's take a look at each class in turn with some code examples.
This is the primary class for the portlet and inherits from the PortletAdaptor class provided by the WebSphere Portal API. Taking a lightweight controller approach to designing the portlet, this class is primarily a lightweight object containing very little business logic. The methods within the class are standard methods outlined for all portlet controller classes.
package com.ibm.wps.manageitems;
import java.io.*;
import java.util.*;
import com.ibm.wps.engine.*;
import org.apache.jetspeed.portlet.*;
import org.apache.jetspeed.portlet.event.*;
import org.apache.jetspeed.portlets.*;
public class ManageItemsPortletHTMLController extends PortletAdapter
implements PortletTitleListener, ActionListener {
public void init(PortletConfig portletConfig) throws UnavailableException {
super.init(portletConfig);
}
public void doTitle(PortletRequest request, PortletResponse response) {
}
|
The actionPerformed() method performs a lot of the controller logic for this portlet. In this example the method is a series of if statements that divert control to different locations within our utility class.
public void actionPerformed(ActionEvent event) {
PortletRequest request = event.getRequest();
PortletSession session = request.getPortletSession();
PortletAction _action = event.getAction();
DefaultPortletAction action;
if (_action instanceof DefaultPortletAction) {
action = (DefaultPortletAction)_action;
// Handle ACTION events
if (action.getName().equals(ManageItemsUtil.ACTION_SEARCH)) {
bean = ManageItemsUtil.searchItems(this, request);
session.setAttribute(ManageItemsUtil.TARGET_PAGE,
ManageItemsPortletUtil.JSPSEARCHRESULTS);
session.setAttribute("ManageItemsBean", bean);
}
else if (action.getName().equals(ManageItemsUtil.ACTION_CREATE)) {
bean = ManageItemsUtil.createItem(this, request);
session.setAttribute(ManageItemsUtil.TARGET_PAGE,
ManageItemsUtil.JSPConfirm);
session.setAttribute("ManageItemsBean", bean);
}
else if (action.getName().equals(ManageItemsUtil.ACTION_SAVE)) {
bean = ManageItemsUtil.saveItem(this, request);
bean.clearErrors();
bean.clearValues();
session.setAttribute(ManageItemsUtil.TARGET_PAGE,
ManageItemsUtil.JSPSaveResults);
session.setAttribute("ManageItemsBean", bean);
}
}
}
|
The doView() method displays various
JSPs that are used in our portlet for user input and to display
results. It acts as a controller method that sets up and then displays
the correct JSP. The JSP to be displayed is determined by the actionPerformed()
method above.
public void doView(PortletRequest request, PortletResponse response)
throws PortletException, IOException {
PrintWriter writer = response.getWriter();
PortletContext context = getPortletConfig().getContext();
PortletSession session = request.getPortletSession();
ManageItemsBean bean = null;
// Set initial jspName to JSPMain.
// Use this as the default if TARGET_JSP
String displayJsp = null;
String jspPrefix = "/jsp/";
String jspName = ManageItemUtil.JSPMain;
String tempJsp = (String) session.getAttribute(ManageItemsUtil.TARGET_PAGE);
if (tempJsp != null) {
displayJsp = jspPrefix + tempJsp;
} else {
displayJsp = jspPrefix + jspName;
}
try {
// Extract ManageItemsBean from session
bean = (ManageItemsBean) session.getAttribute("ManageItemstBean");
// Keep the bean from session if it exists
if (bean != null) {
} else {
// Instantiate a new bean if it doesn't already exist
}
bean = ManageItemsUtil.initItemsBean(this, request);
}
// Put the bean back into session
session.setAttribute("ManageItemsBean", bean);
// Delegate the rendering to displayJsp
context.include(displayJsp, request, response);
// Log debug information
if (getPortletLog().isDebugEnabled()) {
getPortletLog().debug("++++ Set display JSP to " + displayJsp);
}
} catch (Exception ex) {
getPortletLog()Debug(ex.getMessage());
ex.printStackTrace(System.out);
}
}
public void doHelp(PortletRequest request, PortletResponse response)
throws PortletException, IOException {
}
public void doEdit(PortletRequest request, PortletResponse response)
throws PortletException, IOException {
}
public void doConfigure(PortletRequest request, PortletResponse response)
throws PortletException, IOException {
}
}
|
The manageItemsUtil class implements a few basic
utility functions that are needed by the other classes and some JSPs.
It also abstracts most of the business logic needed for the portlet.
It will do this either by including business logic itself into its
methods, or by handing the logic off to another helper class, portlet
service, or an EJB.
package com.ibm.wps.manageitems;
import java.io.*;
import java.util.*;
Import java.text.*;
Import org.apache.jetspeed.portlet.*;
Import org.apache.jetspeed.portlet.event.*;
Import org.apache.jetspeed.util.*;
public class ManageItemPortletUtil {
public final static String ACTION_CREATE = "createItemAction";
public static final String ACTION_DELETE = "deleteItemAction";
public static final String ACTION_EDIT = "editItemAction";
public static final String ACTION_SEARCH = "searchItemAction";
public static final String ACTION_SAVE = "saveItemAction";
public static final String JSP_ADD = "AddItem.jsp";
public static final String JSP_CONFIRM = "ConfirmItem.jsp";
public static final String JSP_EDIT = "EditItem.jsp";
public static final String JSP_MAIN = "Index.jsp";
public static final String JSP_SEARCH_RESULTS = "SearchResults.jsp";
public static final String JSP_SAVE_RESULTS = "SaveResults.jsp";
public static final String CALLING_PAGE = "callingPage";
public static final String TARGET_PAGE = "targetPage";
|
The getNewActionURI() method is used
primarily by the JSPs within the portlet to create return and action
URIs within a JSP page. There are two versions of this method: a
single URI version shown first, and a second version that allows
for a parameter to be passed with the URI.
/**
* Method: getNewActionURI(PortletResponse, String)
* Return: String
* Description: Build an action URI
*/
public static String getNewActionURI(PortletResponse request,
String actionName) {
PortletURI portletURI = request.createReturnURI();
DefaultPortletAction action = new DefaultPortletAction(actionName);
portletURI.addAction(action);
return portletURI.toString();
}
/**
* Method: getNewActionURI(PortletResponse, String, String, String )
* Return: String
* Description: Build an action URI with additional parameters
*/
public static String getNewActionURI(PortletResponse request,
String actionName, String Param, String Value) {
PortletURI portletURI = request.createURI();
PortletAction portletAction = new DefaultPortletAction(actionName);
portletURI.addAction(portletAction);
portletURI.addParameter(Param, Value);
return portletURI.toString();
}
|
The initManageItemsBean() method
is an optional method that can be used to initialize the portlet
bean if necessary. This method is not required if your bean is very
simple.
Public static ManageItemsBean initManageItemsBean(PortletAdapter portlet,
PortletRequest request) {
ManageItemsBean bean = new ManageItemsBean();
//initialize bean here if necessary
return bean;
}
|
The searchItems() method is provided
here as an example of where business logic could be placed in this
type of portlet. The idea is to keep the controller class as simple
as possible to allow business logic to be abstracted to a helper
class. This method can implement the business logic itself, or it
can access a portlet service or EJB if required. Additional methods
of this type will be necessary for a portlet implemented with complete
functionality.
Public static ManageItemsBean searchItems(PortletAdapter portlet,
PortletRequest request) {
ManageItemsBean bean = new ManageItemsBean();
//business logic goes here!
return bean;
}
}
|
The bean is used as our primary storage and communication device with the JSP. We cache the bean in the PortletSession for the life of the portlet instance, and the portlet updates the data within the bean as necessary. Since the portlet is being designed using a Model 2 JSP Architecture, the bean plays an important role in our design. In Figure 3 above, I have included a set of getters and setters to simulate what would probably be needed to implement the search functionality we are discussing. Those getters and setters should be modified for your own implementation.
With core classes and interactions in place, we can take a look at the presentation layer necessary to complete our portlet. As mentioned earlier, the example follows a familiar Model-View-Controller approach taking full advantage of J2EE best practices in developing Web applications. JSPs play a major role in that approach.
Since JSPs are a hybrid between HTML and the Java language, it can be difficult to attain complete separation of the presentation layer. Some opportunity usually presents itself to sneak some business logic into a JSP. There isn't a perfect way to keep this from happening in a development effort. A good design can help to avoid it, but even the best designs can't cover every contingency or scope change. Experienced developers who understand the concepts of proper development as well as the language itself can help to ensure that any business logic that does appears within a JSP is limited and properly designed.
For our example we will add two JSP pages. Notice in Figure 4, that for each JSP added to the model we also added an associated HTML page. This association allows us to illustrate in our model a separation between server and client-side interaction. For the Manage Items portlet we have added the following pages:
- Main.jsp
- This is the main JSP that is displayed by default. The sample code
for the
doView()method shows an example of setting up theTARGET_PAGEto display this page if no other page is set in theactionHandler()method. - Main.html
- This is the client side version of the
Main.jsp. Included in this page is a search form that triggers the search action. The action from this page triggers theactionPerformed()method to initiate a search. - SearchResults.jsp
- This JSP gets the results from the search action in the form of a Java bean and formats the corresponding HTML page to display the search results.
- SearchResults.html
- This is the client side display of the search results.
Expanding the original class diagram to use these new pieces of functionality provides us a better overview of the full functionality of our portlet. In the new class diagram, (Figure 4) we see a complete picture of all the components used for the search functionality for our portlet.
Figure 4. Search class diagram

While a class diagram allows us to see objects from a component view, it does not provide a complete view of the sequence of events that will take place in our portlet. We can see better detail for the search function with a sequence diagram showing how the search action takes place. Figure 5 gives a picture of how our components will actually interact with one another during the search process. Notice that we use method names, stereotypes and common English to describe the interactions between objects.
Figure 5. Search sequence diagram

English text interactions such as "Determine Action" can be decomposed down to a very fine level of detail, captured into a second design document or work product, or handed off to a developer to complete during implementation. There are no rules as to the level of detail that your models have to follow, and the effort and level of detail involved should be reflective of the nature of the functionality and the size of the project.
When designing a JSP, we should take advantage
of the framework we used to set up our portlet controller and other
classes. In our design we depend upon a Java bean to provide us
with any information we need to display within the JSP. Making this
assumption we can just look to the bean. When coding JSPs, start
by importing any packages that will be needed. This includes adding
your portlet package since we will be accessing the manageItemsUtil()
class. Also any needed tag libraries should be included here.
Tag libraries and portlet services can be modeled in your class diagrams similar to the way that Java beans and utility classes are modeled. If you have developed custom tag libraries that you want to include and model with JSP components, they can be set up in your class diagram using an include stereotype. Before you start to work with these items, you should look at all of your portlets and coalesce similar classes into services and libraries.
<%@ page import="org.apache.jetspeed.portlet.service.*" %>
<%@ page import="org.apache.jetspeed.portlet.*" %>
<%@ page import="org.apache.jetspeed.portletcontainer.PortletRequestImpl" % >
<%@ page import="org.apache.jetspeed.portlet.*" %>
<%@ page import="com.ibm.wps.engine.RunData" %>
<%@ page import="com.ibm.wps.manageitems.*" %>
<%@ page import="com.ibm.wps.services.authorization.*,
com.ibm.wps.puma.*,com.ibm.wps.util.*" %>
<%@ taglib uri="/WEB-INF/tld/portlet.tld" prefix="portletAPI" %>
<portletAPI:init/>
<jsp:useBean id="ManageItemsBean"
class="com.ibm.wps.manageitems.ManageItemsBean" scope="session" />
|
When you've set up the headers within a JSP, you
can create an action handler URI similar to the following example.
This example creates an ACTION_CREATE link. When called,
it triggers that section of the actionPerformed() method
coded to recognize this parameter. The action handler will then
perform whatever action is required, and set the TARGET
to the next JSP to display.
<a href="<%= ManageItemsUtil.getNewActionURI(portletResponse,
ManageItemsUtil.ACTION_CREATE) %>">Add Item</a>
|
You can create the search form in the model using the following code sample. It also uses an action handler URI, and encodes form parameters using the portlet tag library. This library isn't modeled in our system because it is part of the supplied API for WebSphere Portal. Modeling components that are already supplied within WebSphere Portal is possible, but can add to the complexity of the model. You should only go to this level of detail in cases where you really want to show particular detail about using a particular API.
<form name="itemsearchform"
action="<%= ManageItemUtils.getNewActionURI(portletResponse,
ManageItemsUtil.ACTION_SEARCH) %>" method="post">
<table border="0" cellpadding="3" cellspacing = "3">
<tr>
<td align="left">Customer ID:</td>
<td align="left">
<input type="text" name="" value="<%= ManageItemBean.getItemName() %>">
</td>
</tr>
<tr>
<tr>
<td align="right">
<input type="submit" name="" value="" />">
<br>
</td>
</tr>
</table>
</form>
|
Development, deployment and beyond
Even with only a single model in place, moving to micro design and development for this piece of functionality is a much easier process. After all the major components in a system (or in our case subsystem) are fully designed and coalesced, developers can see, not only what, but how specific objects should best be implemented. Changes identified during development can be transcribed within the model and reflected throughout the system.
In Figure 6 I have laid out the package structure (within the modeling tool) of the objects, similar to how I might expect them to be created during development. This approach helps to group connected items together in a format similar to how they are developed, and eventually deployed onto the target system.
Figure 6. Model browser

Used in combination with other work products such as wire frame models and design documents, UML can be a powerful way to communicate requirements and design to developers. The code samples provided above provide you with an example of the objects being modeled. They also hopefully provide some examples of best practices for portlet development using JSPs and utility classes. In closing, I hope to have provided enough information for you to start using UML when designing your own portal applications. In future articles I will try and build upon what has been presented here to include modeling portlet services and extend the portlet classes to take advantage of these services.
-
Developing Enterprise Java Applications with J2EE and UML. By Khawar Zaman Ahmed
and Cary E. Umrysh
-
Applied Java Patterns. By Stephen Stelting and Olav Maasen

Anthony (Joey) Bernal is a Senior I/T Specialist with the e-Workplaces/Knowledge and Content Management Practice with IBM Global Services. You can reach Joey at abernal@us.ibm.com.




