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:

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.
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:
- Copy menu-example.war to tomcat installation folder\webapps.
- Restart Tomcat to deploy the application.
- Adjust xmlmenu.jsp and jdbcmenu.jsp to fit your environment.
- Create a new database table structure and import seed data by running the menu.sql file.
- To access the JSP that builds menus from XML, visit localhost:8080/menu-example/xmlmenu.jsp.
- To access the JSP that builds menus from JDBC, visit localhost:8080/menu-example/jdbcmenu.jsp.
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
- For more information on menu tags, view the menutag.html documentation
- Design Patterns, Eric Gamma, Richard Helm, Ralph Johnson, John
Vlissides (Addison-Wesley Publishing Co., 1995; ISBN: 0201633612)
- JSP Tag
Libraries
Prabu Arumugam
is a software architect and senior Java developer at Forest Express, LLC.
Return to ONJava.com.