Package org.bibeault.frontman

Bear Bibeault's Front Man™ (called simply "Front Man" from here on) is an implementation of the Front Controller and Command patterns that serves as an ultra-lightweight framework (if you could call it that) for quickly creating web applications of all sizes.

See:
          Description

Interface Summary
Command Interface that defines a unit of controller execution: a "Command".
CommandContext Defines the interface for an object instance passed to the execute() method of a Command instance.
 

Class Summary
CommandBroker A simple Front Controller using a simple "configuration by convention" mechanism to locate Command classes and View resources.
CommandContextImplementation A context object that maintains the state information for the invocation of a command, as well as making various useful methods available to Command implementations.
ViewBroker  
 

Enum Summary
ScopedContext Enumeration modeling the four context scopes.
 

Exception Summary
CommandNotFoundException An extension of ServletException that is thrown by the Command Broker in the event that an invalid command verb is referenced.
ViewNotFoundException An extension of ServletException that is thrown by the Command Broker in the event that an invalid view name is referenced.
 

Annotation Types Summary
FrontmanCommand Annotation to associate a command implementation with its verb.
 

Package org.bibeault.frontman Description

Bear Bibeault's Front Man™ (called simply "Front Man" from here on) is an implementation of the Front Controller and Command patterns that serves as an ultra-lightweight framework (if you could call it that) for quickly creating web applications of all sizes.

 

1.0 Purpose of Front Man

The purpose of Front Man is to provide an ultra-lightweight web framework that adheres to the principle that the answer to the question "How big should a web framework be?" is "Barely enough". It aims to provide the basic plumbing for Model 2-patterned web applications while achieving the project goals of:

2.0 Setting up Front Man

Overview of set up steps:

  1. Drop the Front Man jar file into your application's WEB-INF/lib folder.
  2. Grab the Jakarta Commons Logging jar file and drop it into WEB-INF/lib.
  3. Add the <servlet> and <servlet-mapping> entries for the Command Broker servlet in the deployment descriptor (web.xml).
  4. Optionally, create properties files to define explicit mappings for the command verbs and view names respectively.
  5. Start writing your pages and commands!

Let's take a look at each of these steps in detail.

2.1 Add the Jar Files to the Applications

Once you have obtained the frontman-1.6.1.jar file, just drop it into your web application's WEB-INF/lib folder.

The only other jar file necessary jar is Jakarta Commons Logging. This allows the logging performed by Front Man to hook into either Log4J or the java.util.logging package as defined by your web app. Obtain this jar from the Jakarta Project site.

2.2 Set up the Deployment Descriptor

The Front Man front controller, the CommandBroker class, must be established as a servlet in the deployment descriptor, and mapped to an appropriate URL pattern. Initialization parameters specify how command verbs are mapped to their corresponding command classes, and how view names are mapped to the path of their view resources. These initialization parameters are defined as:

Init Param Name Description
commandsPath

Defines the root path at which to automatically search for command classes with the @FrontmanCommand() annotation, or when employing implicit command mapping by convention (command mapping is explained in detail in Section 3.1.

This parameter can be omitted only if a commandVerbsProperties parameter is specified.

viewsPath

Defines the root path at which to search for view resources relative to the context root. The full path for the resource is created by appending a slash followed by the view name, followed by the string ".jsp".

For example, if the viewsPath is defined as /WEB-INF/pages, a view name of something would be mapped to a path of /WEB-INF/pages/something.jsp, while a view name of xyz/hello would map to /WEB-INF/pages/xyz/hello.jsp.

Note that this implicit mapping is attempted only if no explicit mapping for the views names is found in a properties bundle defined by viewNamesproperties.

This parameter is optional.

commandVerbsProperties

Defines the context-relative location of a properties file that contains explicit command verb to Command class name mappings.

This parameter is optional if a commandsPath parameter is provided.

viewNamesProperties

Defines the context-relative location of a properties file that contains explicit view name to view resource path mappings.

This parameter is optional. Note that if neither of a viewNamesProperties or viewsPath parameter is specified, view names cannot be used and all views need to be referenced by explicit URL. It is highly recommended to use view names.

A typical such declaration might look like:

<servlet>
  <servlet-name>CommandBroker</servlet-name>
  <servlet-class>org.bibeault.frontman.CommandBroker</servlet-class>
  <init-param>
    <param-name>commandsPath</param-name>
    <param-value>com.mydomain.projectname.commands</param-value>
  </init-param>
  <init-param>
    <param-name>viewsPath</param-name>
    <param-value>/WEB-INF/pages</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
          

Another possibility:

<servlet>
  <servlet-name>CommandBroker</servlet-name>
  <servlet-class>org.bibeault.frontman.CommandBroker</servlet-class>
  <init-param>
    <param-name>commandVerbsProperties</param-name>
    <param-value>/WEB-INF/command.verbs.properties</param-value>
  </init-param>
  <init-param>
    <param-name>viewNamesProperties</param-name>
    <param-value>/WEB-INF/view.names.properties</param-value>
  </init-param>
  <load-on-startup>1</load-on-startup>
</servlet>
          

The optional commandVerbsProperties and viewNamesProperties init parameters can be used to specify the path where the mapping property files can be found. These path values must begin with "/" and are referenced relative to the context root.

The servlet mapping for this controller is typically along the lines of:

<servlet-mapping>
  <servlet-name>CommandBroker</servlet-name>
  <url-pattern>/command/*</url-pattern>
</servlet-mapping>
          

The command prefix to this mapping can be any word you would like, but the pattern for the mapping must be as shown. Use of the conventional prefix command is highly recommended unless it would cause a conflict with a URL pattern that you are not at liberty to change.

This mapping establishes URLs to the various commands you will define as:

  http://yourserver.com/contextPath/command/commandVerb
          
where:
  • yourserver.com is the domain name for your server.
  • contextPath is the context path established for your application.
  • commandVerb is the verb for a command.

As an example, let's say that you have defined a command verb such as doSomethingWonderful in your properties file, the URL to execute that command would be:

  http://yourserver.com/contextPath/command/doSomethingWonderful
          

2.3 Set Up Optional Mapping Properties Files

The optional configuration files that map command class names to their verbs, and view names to their resource URLs, are refreshingly simple. They are merely run-of-the-mill Java properties files.

2.3.1 The Command Verbs Properties File

The Command Verbs Properties File is used to explicitly associate command verbs with the command classes that should be executed when that verb is used in a URL to the Front Man command broker servlet. This file is identified to the system via the optional commandVerbsProperties init parameter to that servlet.

The properties defined in this file map command verbs to the names of the classes, each implementing the Command interface, that will be invoked when that verb is specified in a URL. A typical entry might look like:

  doSomethingWonderful=com.whatever.someproject.commands.DoSomethingWonderfulCommand

A useful convention is for command verbs to start with a lowercase character, and a verb that describes the action to be taken by the command.

See Section 3.1 for details on how commands verbs are mapped to their respective Command classes.

2.3.2 The View Names Properties File

The View Names Properties File is used to associate view names with the context-relative URLs that locate the resource (usually a JSP or HTML file) invoked when the view name is referenced. This file is identified to the system via the viewNamesProperties init parameter to the command broker servlet.

View names are most often referenced from within commands as the target of a forward or redirect operation. By abstracting the view names from their physical location, changes in the view resource hierarchy will not require any changes to the code as physical URLs are not used to reference the resources.

Within the properties file, each entry associates a view name with the location of the named resource. Some typical entries in this properties file could be:

  ErrorPage=/errors.jsp
  HomePage=/WEB-INF/pages/home.jsp
  LoginPage=/WEB-INF/pages/login.jsp
  ProfileEntryForm=/WEB-INF/pages/profile.entry.jsp
            

As with command verbs, a recommended convention has been established that seems to help keep things tidy:

  • View names should start with an uppercase character and be a grammatical noun; typically a compound noun that uniquely identifies the resource.
  • Typical suffixes like "Page" or "Form" help to clearly indicate the usage of the resource by inspection.

Note that in this example most of the pages are hidden in the folder hierarchy under the WEB-INF folder. This is typical of Model 2 web applications where is it highly unusual to visit a view without first going through a controller. Placing the JSP files under WEB-INF prevents any direct access via URL.

2.4 Write Your Command Classes

That's all there is to the setup. You are now ready to start writing your application, particularly the command classes.

All commands must implement the Command interface which consists of a single method to be called when the Command is to perform its function:

  public void execute( CommandContext commandContext ) throws ServletException, IOException;

A context object of type CommandContext is passed to this method which not only gives the method access to its environment, it provides a bevy of useful methods that the Command can take advantage of; methods to easily forward or redirect to other Commands or views via their abstracted names, for example.

2.5 Write Your View Pages

Go ahead and write your JSP pages. There is no required "goo" that you must put on the pages in order for them to work. No required tags. No required declarations. No required directives.

The use of JSP scriptless pages that employ the EL and JSTL to best advantage is highly recommended.

3.0 Usage Notes and Tips

These sections contain information on how Front Man works as well as various tips and tricks that you can use to take best advantage of Front Man.

3.1 How Command Verbs are Mapped to Command Classes

Front Man gives you three choices regarding how command verbs in the URL are mapped to their respective command classes. You can choose whichever means best suits your project and programming style, and you can even use all three approaches within the same web application.

The three approaches, in order of precedence from highest to lowest are:

  1. Explicit mappings in a command verbs properties file
  2. Explicit Java annotations on the command classes
  3. Implicit mapping by class name
Each of these approaches is described in the following sections

3.1.1 Explicit Command Mapping Using a Properties File

Within the properties file, each entry associates a command verb with the class name of the concrete command class that is to be executed for that verb. Some typical entries in this properties file could be:

  doSomethingWonderful=com.whatever.someproject.commands.DoSomethingWonderfulCommand
  login=com.whatever.someproject.commands.LoginCommand
  viewHomePage=com.whatever.someproject.commands.ViewHomePageCommand
  viewLoginPage=com.whatever.someproject.commands.ViewLoginPageCommand
            

Note the naming patterns used for command verbs and for the corresponding command classes. It is highly recommended to follow these conventions as it has proved to keep URLs and command code as readable and understandable as possible. Notably:

  • Command verbs should start with a grammatical verb and a lowercase character. The remainder of the name uses typical Java "camel case" and should adhere to the rules for Java identifiers.
  • Command class names should be the same as the command verb with the first character upper-cased and the suffix "Command" added.
You are, of course, free to come up with your own conventions, but time and usage has proved that the above simple conventions keep things tidy and understandable.

These mappings take precedence over Command class annotations and any implied mapping.

3.1.2 Explicit Command Mapping Using Java Annotations

For those that don't wish to use external properties files to associate command verbs to Command classes, Front Man defines a Java annotation that can be used to directly associate a Command class with a command verb directly in the code for the Command class.

This annotation is @FrontmanCommand() and it takes a single text value that defines the command verb to be associated with the Command class.

For example, if we defined a Command class named MyWonderfulCommand, and wished for it to be invoked via command verb doSomethingWonderful, we would write:

          @FrontmanCommand("doSomethingWonderful")
          public class MyWonderfulCommand implements Command {
            

Note that only classes that implement the Command interface and are in the classpath hierarchy identified by the commandsPath init parameter will be considered for command mappings.

Any duplicate mappings between the annotations and those defined in a command mapping properties file will resolve to the mapping specified in the properties file.

3.1.3 Implicit Command Mappings by Class Name

Another means to map command verbs to their respective Command classes is to allow Front Man to surmise the name of the command class from the command verb itself.

In this approach, the command class is located relative to the path provided in the commandsPath init parameter.

The full class name for the command is created by concatenating the following values:

  • the value of commandsPath
  • a period character
  • the command verb with first character uppercased
  • the string Command

For example, if the commandsPath is defined as org.something.commands, a command verb of doSomething would be mapped to a command class name of org.something.commands.DoSomethingCommand, while a command verb of xyz.sayHello would map to org.something.commands.xyz.SayHelloCommand.

Note that this implicit mapping is attempted only if no explicit mapping for the command verb is found in an explicit property or annotation mapping.

3.2 Command Verb and View Name Name-spacing

In some projects it may make sense to namespace the command verbs in the project. This can easily be performed by adding a namespace suffix to the verb or name and using the period character as a separator.

An example where such segregation is useful might be a web application that requires authentication. Most pages in the application require a logged-in user, but obviously some pages and commands, such as the login form itself, should not require a logged-in user. Commands and views exempt from authentication could belong to one namespace, and commands and views requiring authentication to others.

It would then be a simple matter to write a servlet filter that would use the namespace to determine if the command being invoked requires authentication or not by looking at the namespace.

There are many other situations in which name-spacing your command verbs and view names might be useful. It's a handy tip that can make your code and life simpler.

When explicitly defining command verb mappings (or view names) within a properties file or via Java annotations, it's a simple matter to simply include the namespace as part of the verb; for example: login.viewLoginPage, core.subsystem.doSomethingWonderful or commerce.ShoppingCartView. In these case, the period characters are not significant and are just part of the mapping key.

When using the implicit command mapping by class name approach, however, the period character and the namespace names are significant in that they represent the package structure of the command class relative to the path defined by the commandsPath init parameter. For example, a command verb of core.subsystem.doSomethingWonderful would implicitly map to a class name of core.subsystem.DoSomethingWonderfulCommand relative to the package defined by commandsPath.

View names can use the folder structure for name-spacing using the slash (/) character as a spearator. The implicit mapping of such name-spaced views represent the folder structure where the corresponding JSP is located. For example, a view name of core/commerce.details would implicitly map to the file core/commerce.details.jsp relative to the folder specified by the viewsPath init parameter.