ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 See this if you're having trouble printing code examples


A Custom JSP Tag Library for Dynamic Menus

by Prabu Arumugam
04/09/2003

Menus are critical components of software applications. Implementing a static menu is relatively easy--just categorize and customize the application's functionality once. Implementing a dynamic menu, unique for each user depending on his or her profile and preferences, is both challenging and cumbersome.

While the Java programming language has built-in support to create basic menu structures, JSP lacks support. Web applications must use either Java applets or JavaScript to implement menu structures. Many web application developers prefer JavaScript to applets for simplicity and ease of deployment. This article describes a custom tag library that simplifies the process of generating JavaScript dynamically. The design and implementation of the tag library are covered in detail.

Design Approach

Our design goal is an object model that represents hierarchical data and contains methods to generate JavaScript.

Each menu in the hierarchical menu system can contain one or more simple menu items or sub menus, which in turn may contain simple menu items and submenus. The simple menu provides access to the application-specific functionality. Regardless of the menu type, the menu object should be capable of generating appropriate JavaScript.

Based on a composite design pattern, the simple menu represents the menu at the leaf level, while the composite menu represents groups of submenus and simple menus in the menu structure. In other words, the Composite can contain a list of SimpleMenu objects and other CompositeMenu objects. The Menu abstract class represents a menu in the hierarchy and defines a render method for subclasses to provide their own implementations.

Figure 1 illustrates the composite design pattern:

UML for our menu classes
Figure 1. UML for our menu classes

The SimpleMenu renders menu items with URLs that point to application functionality. The CompositeMenu overrides the render method by looping through its list of submenus, calling render on each. Remember, lists can contain both menu items and sub menus, so menus can be multiple levels deep.

Listing 1 shows the render method of CompositeMenu and SimpleMenu. Both methods just produce JavaScript, which calls existing functions defined in dynamicmenu.js. Functions in this file are responsible for creating menus in the browser. The design and the implementation of these functions are beyond the scope of this article.

The render Method of SimpleMenu

StringBuffer sb = new StringBuffer();
sb.append("addmenuitem(");
sb.append("\"" + getLevelCoord() + "\",");
sb.append("\"" + getMenuName() + "\",");
sb.append("\"" + getUrl() + "\",");
sb.append("\"black\",\"FAEBD7\",\"white\", \"3366CC\",\"white\",
    \"3366CC\",\"font-family:Tahoma, Verdana, Arial; 
    font-size:12px;font-weight:normal,text-decoration:none;padding: 4px\");");
sb.append("\n");
return sb.toString();

The render Method of CompositeMenu

StringBuffer sb = new StringBuffer();
sb.append("addmenuitem(");
sb.append("\"" + getLevelCoord() + "\",");
sb.append("\"" + getMenuName() + "\",");
if (null == getUrl())
    sb.append("null" + ",");
else
    sb.append("\"" + getUrl() + "\",");
sb.append("\"black\",\"FAEBD7\",\"white\",\"3366CC\",\"white\",\"3366CC\",
        \"font-family:Tahoma, Verdana, Arial; font-size:12px;
        font-weight:normal,text-decoration:none;padding: 4px\");");

sb.append("\n");
Iterator it = list.iterator();
int i=1;
while(it.hasNext())
{
    Menu menu = (Menu)it.next();
    menu.setLevelCoord(getLevelCoord() + "," + i);
    sb.append(menu.render());
    i++;
}
return sb.toString();

Menu Data Source

The menu builder is responsible for building menus from the data source. Menu data is hierarchical by nature. It can come from any source that supports hierarchical data representation. We have implemented builders for two commonly used data sources: XML and a database. However, it is easy to develop other builders using this approach.

XMLMenuBuilder

Since menu structures and XML structures are both hierarchical, XML can easily represent menu data. XMLMenuBuilder accepts the name of an XML file that contains menu definitions and parses the XML document to build the dynamic menu. The <menu> element in the XML document can represent menu items or submenus, which in turn can contain menu items or submenus.

JDBCMenuBuilder

Despite the fact that database tables represent relational data, tables can still be used to represent hierarchical data. The HIERARCHYMENU table represents hierarchical menu data. JDBCMenuBuilder accepts database source information in order to select menu data from the HIERARCHYMENU table.

Menu Tag Library

The menu tag library manages the complex process of creating menus in JavaScript. The menu tag itself is an abstract class that extends the TagSupport class and overrides the doStartTag and doEndTag methods. The getMenu method, which is a template method and should be overridden in the subclasses, provides JavaScript to add menu items in the menu structure created in the doStartTag method. Subclasses of the menu tag override the getMenu method, which uses menu builders to render menu data from the data source.

The Dynamic Menu Tag Library contains two tags: JDBCMenuTag and XMLMenuTag. JDBCMenuTag uses JDBCBuilder to build the menu structure from a database source, while XMLMenuTag uses XMLBuilder to build the menu structure from an XML data source. The documentation provides complete instructions for using the tag library.

The current version of this tag does have a few limitations, however. It does not yet comprehend the association between the user and the menu, which is different for each application. Also, the library does not provide support for specifying the color or font for menu items.

Download Source Code

menu.zip
menu-example.war

Menu Tag Sample Application

The menu-example.war file contains JSP pages that use this tag library. Follow these instructions to deploy the application on Tomcat:

Conclusion

The Dynamic Menu Tag Library manages the complex process of creating menus in JavaScript, and allows web applications to build dynamic, hierarchical menus from a database or an XML source.

Resources

Prabu Arumugam is a software architect and senior Java developer at Forest Express, LLC.


Return to ONJava.com.

Copyright © 2009 O'Reilly Media, Inc.