JSF in Chains: Some Code

Some people have asked to see JSF + Chain code, so here's some code with brief
narration.

This is a simple login application with a login page that has prompts for username
and password.

Here's the password field in the JSP page:

<h:inputSecret id="password" required="true"
        validator="#{loginPage.validatePassword}" redisplay="true">
      ...
</h:inputSecret>

Here's the backing bean:

public class LoginPage {
   ...
   private LoginContext loginContext = null;
   ...
   private ValidatePasswordCommand validatePasswordCommand =
       new ValidatePasswordCommand();
   ...
   public void validatePassword(FacesContext context, UIComponent component,
                        Object value) throws ValidatorException {
      logger.info("Validating password");
      loginContext.setPassword((String)value);
      boolean stop = validatePasswordCommand.execute(loginContext);
      if(stop)
         throw new ValidatorException(com.corejsf.util.Messages.
                            getMessage("messages", "badUserPassword", null));
   }
   ...
}

The validatePassword method sets up the login context and invokes the validate
password command. The outcome of that boolean method determines whether a validation
exception is thrown. (In Chain, commands can be chained together. A command's
execute method returns a boolean: true means that processing is finished and
therefore the chain is short circuited. false means processing is not finished and
Chain transfers control to the next command in the chain.)

The login context has three properties that are of interest to the commands:
username, password, user and sessionMap. I'll spare you those boring details.

Here's the command:

public class ValidatePasswordCommand implements Command {
   private static final Logger logger = Logger.getLogger(
                           ValidatePasswordCommand.class.getName());
   public boolean execute(Context context) {
      boolean stop;

      stop = (((LoginContext)context).getUser() == null) ? true : false;

      if(stop) logger.info("invalid user");
      else     logger.info("valid user");

      return stop;
   }
}

Admittedly, all we've done is move one line of code (the call to get a user) from
the backing bean into a command. We also had to implement a context class to hold
state for our commands. Was it worth the effort?

For this simple example alone, no, it wasn't worth the effort. But if our backing
beans consistently delegate to commands or chains, we cleanly separate JSF-specific
code from JSF-nonspecific code. Our backing beans do only what they should--delegate
business logic and throw validation exceptions, as appropriate--and nothing more.
Classes that mind their own business in such a manner are a hallmark of good
object-oriented design.

Furthermore, a command's only view of the world is its context (in this case, the
login context), so commands are eminently reusable, irrespective of the surrounding
framework. And they're easy to test with mock contexts.

I've also restricted model access to context objects, so far that's the LoginContext
class. That restriction defines a narrow conduit between the UI and model, one that
I can easily mock when I want to rock on with UI development while the model guys
sit around debating what the database schema should look like.

I should also note that this is a very simple example of Apache Commons Chain. In
fact, I'm not using chains at all, just commands. btw, a chain is-a command, so you
create a tree of commands.

Finally, this is an interesting example from JSF's perspective. JSF, like Spring
MVC, uses value bindings to directly wire HTML components to JavaBean properties.
In first-generation frameworks like Struts, it was up to you to write code to do
that: actions and forms to shuttle data from web form to JavaBean property. With
JSF, you are freed from implementing all of that infrastructure. Can I get an
Amen? See this blog entry for more details.

JSF subsumes controller functionality that, in a Struts world, is on the shoulders
of the developer, namely shuttling values from web forms to bean properties and
vice versa. That begs the question: does JSF need infrastructure like Struts actions
and forms? In all likeliehood, you will want some infrastructure around your JSF
"actions", regardless of whether your framework is shuttling values for you. For
JSF developers, Apache Commons Chain is a solid implementation of that
infrastructure. Of course, if you are hungry for more, then you might consider
Shale. More on that later...