<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<article>
  <title>Jakarta Commons Chain of Responsibility</title>

  <authorblurb>
    <para>The Commons Chain Cookbook is an extract from the Jakarta Cookbook
    [ISBN: TBA] which has been graciously donated to the Apache Software
    Foundation by O'Reilly &amp;&nbsp;Associates. The publication date for the
    Jakarta Cookbook has not been set.</para>
  </authorblurb>

  <section>
    <title>Introduction</title>

    <para>The essence of computing might be that for any expected input (A),
    we return the expected output (B). The challenge is getting from (A) to
    (B). For a simple program, (A) to (B) might be a single transformation.
    Say, shifting a character code 32 digits so that "a" becomes "A". In a
    complex application, A to B can be a long and winding road.</para>

    <para>We might need to confirm that the user is authorized to create (B)
    from (A). We might need to find that (A) is valid input for (B). We might
    need to convert (A) from another character set. We may need to insert a
    preamble before writing (B). We may need to merge another resource with
    (A) before creating (B). Meanwhile, iIf anything goes wrong during
    processing, the error must be handled, and even logged. Some tasks might
    be able to continue after a non-fatal error, or, if the error is fatal,
    all process might need to halt.</para>

    <para>There are many different ways programmers organize processing logic
    within an application. Often, the difference between an elegant
    architecture and a muddled ball-of mud is how control flows from one
    process to another. To realize and retain elegeance, we must organize
    complex, multi-step processes so that they are easy to discover and
    change.</para>

    <para><remark>[TODO:]</remark></para>
  </section>

  <section>
    <title>Separate "business" logic from "presentation" logic</title>

    <para><emphasis>Problem:</emphasis> You want to cleanly separate the
    execution and presentation layers without complicating the design of your
    application.</para>

    <para><citetitle><emphasis>Solution:</emphasis></citetitle> Use the
    <glossterm>Chain of Responsibility</glossterm> and
    <glossterm>Command</glossterm> patterns so that the presentation layer can
    execute a command, or chain of commands, without needing to know how the
    command is implemented.</para>

    <para><emphasis>Discussion</emphasis>: To be useful, most applications
    need to run a process and then tell the client what happened. In practice,
    we find mixing "running" and "telling" together creates code that can be
    hard to test and maintain. If we can have one component run (or execute)
    the process, and another component report (or present) the result, then we
    can test, create, and maintain each component separately. But, how can we
    cleanly separate the execution and presentation layers without
    complicating the design of an application?</para>

    <para>Most application frameworks, especially web application frameworks,
    rely on the Command pattern. An incoming HTTP request is mapped to some
    type of "command" object. The command object takes whatever action is
    required, using information passed in the HTTP request.</para>

    <para><remark><remark>[Glossary: "Chain of Responsibility pattern",
    "Command pattern" entry]</remark></remark></para>

    <figure>
      <title>Using information passed in the request, the Command object takes
      whatever action is required.</title>

      <olink><remark>[TODO: line art.]</remark></olink>
    </figure>

    <para>In practice, there are usually commands within commands. A Command
    object in a web application often looks like a sandwich. First, it does
    some things for the benefit of the presentation layer, then it executes
    the business logic, and then it does some more presentation layer things.
    The problem many developers face is how to cleanly separate the
    <glossterm>business logic</glossterm> in the middle of a web command from
    other necessary tasks that are part of the <glossterm>request/response
    transaction</glossterm>.</para>

    <para><remark><remark>[Glossary: "business logic" , "request/response
    transaction" entry]</remark></remark></para>

    <figure>
      <title>A Command object often looks like a business logic
      sandwich.</title>

      <olink><remark>[TODO: line art.]</remark></olink>
    </figure>

    <para>The <productname>Chain of Responsibility</productname> package in
    the Jakarta Commons [<link
    linkend="???">http://jakarta.apache.org/commons/</link>] combines the
    Command pattern with the classic <glossterm>Chain of Responsibility
    pattern</glossterm> to make it easy to call a business command as part of
    a larger application command. (For more about the patterns, see
    <productname>Design Patterns: Elements of Reusable Object Orientated
    Software</productname> [<productnumber>ISBN
    0-201-63361-2</productnumber>]).</para>

    <para><remark><remark>[Glossary: "Chain of Responsibility pattern"
    entry]</remark></remark></para>

    <para><figure>
        <title>The Chain package makes it easy to call a business operation
        from within a larger transaction.</title>

        <olink>[TODO: line art]</olink>
      </figure></para>

    <para>To implement the patterns, the <classname>Chain</classname> package
    defines five key interfaces:</para>

    <simplelist>
      <member>Context</member>

      <member>Command</member>

      <member>Chain</member>

      <member>Filter</member>

      <member>Catalog</member>
    </simplelist>

    <para><emphasis>Context.</emphasis> A <classname>Context</classname>
    represents the state of an application. In the Chain package,
    <classname>Context</classname> is a marker interface for a
    <classname>java.util.Map</classname>. The Context is an envelope
    containing the attributes needed to complete a transaction. In other
    words, a Context is a stateful object with member values.</para>

    <para><emphasis>Command.</emphasis> A <classname>Command</classname>
    represents a <glossterm>unit of work</glossterm>. A Command has a single
    entry method: <methodname>public boolean execute(Context
    context)</methodname>. A Command acts upon the state passed to it through
    a context object, but retains no state of its own. Commands may be
    assembled into a Chain, so that a complex transaction can be created from
    discrete units of work. If a Command returns <symbol>true</symbol>, then
    other Commands in a Chain should <emphasis>not</emphasis> be executed. If
    a Command returns <symbol>false</symbol>, then other Commands in the Chain
    (if any) may execute.</para>

    <para><remark><remark>[Glossary: "unit of work"
    entry]</remark></remark></para>

    <para><emphasis>Chain.</emphasis> <classname>Chain</classname> implements
    the <classname>Command</classname> interface, so a
    <classname>Chain</classname> can be used interchangeably with a
    <classname>Command</classname>. An application doesn't need to know if
    it's calling a Chain or a Command, so you can refactor from one to the
    other. A Chain can nest other Chains as desired. This property is known as
    the <emphasis><glossterm>Liskov substitution principle</glossterm>.
    </emphasis></para>

    <para><emphasis><remark>[Glossary: "<glossterm>Liskov substitution
    principle</glossterm>" entry]</remark></emphasis></para>

    <para><emphasis>Filter.</emphasis> Ideally, every command would be an
    island. In real life, we sometimes need to allocate resources and be
    assured the resources will be released no matter what happens. A
    <classname>Filter</classname> is a specialized
    <classname>Command</classname> that adds a
    <methodname>postProcess</methodname> method. A
    <classname>Chain</classname> is expected to call the
    <methodname>postProcess</methodname> method of any filters in the chain
    before returning. A Command that implements Filter can safely release any
    resources it allocated through the <methodname>postProcess</methodname>
    method, even if those resources are shared with other Commands.</para>

    <para><emphasis>Catalog.</emphasis> Many applications use "facades" and
    "factories" and other techniques to avoid binding layers too closely
    together. Layers need to interact, but often we don't want them to
    interact at the classname level. A <classname>Catalog</classname> is
    collection of logically named Commands (or Chains) that a client can
    execute, without knowing the Command's classname.</para>

    <para><figure>
        <title>The five core interfaces: Context, Command, Chain, Filter, and
        Catalog.</title>

        <olink><remark>[TODO: UML for Context, Command, Chain, Filter, and
        Catalog.]</remark></olink>
      </figure></para>

    <para>The rest of the chapter features recipes that will help you put the
    Chain of Responsibility package to work in your own applications.</para>
  </section>

  <section>
    <title>Test a Command</title>

    <para><emphasis>Problem:</emphasis> You want to start using
    <classname>Command</classname> objects in your application.</para>

    <para><emphasis>Solution:</emphasis> Use <glossterm>Test Driven
    Development</glossterm> to create a test for a Command, and let the test
    tell you how to write the Command. When the test passes, you will have a
    working Command to integrate into your application.</para>

    <para><emphasis><remark>[Glossary: "<glossterm>Test Driven
    Development</glossterm>" entry]</remark></emphasis></para>

    <para><emphasis>Discussion: </emphasis>Let's say we're working on an
    application that maintains a "<classname>Profile</classname>" object for
    each client. We need to change the state of the Profile during the
    client's "session" with the application, which may span several requests.
    Different application environments may preserve a Profile in different
    ways. A web application may store a Profile as an attribute of the
    HttpSession or as a client-side "cookie". An EJB application may maintain
    a Profile as an attribute of the client's environment. Regardless, you
    would like a single Command that can check to see if a client has a
    Profile object, and, if not, create one. The Command does not know how the
    application stores a Profile, or even if it is stored.</para>

    <para>One reason we use Commands is because they are easy to test. In this
    recipe, let's write a test for our Command. In another recipe, we will
    create the corresponding Command. This approach is known as Test Driven
    Development.</para>

    <para>To test our Command, we can simply</para>

    <orderedlist>
      <listitem>
        <para>Create a Context with a known state</para>
      </listitem>

      <listitem>
        <para>Create a Command instance to test</para>
      </listitem>

      <listitem>
        <para>Execute the Command, passing our Context</para>
      </listitem>

      <listitem>
        <para>Confirm that our Context now contains the expected state</para>
      </listitem>
    </orderedlist>

    <para>For the <classname>Context</classname>, we can use the
    <classname>ContextBase</classname> class provided as part of the Chain
    package. The <classname>ProfileCheck</classname> Command and Profile
    object are shown in the next recipe. The remaining code for our
    <classname>TestProfileCheck</classname> TestCase is shown as Example
    1.</para>

    <example>
      <title>Testing whether a Profile object is created</title>

      <programlisting>package org.apache.commons.mailreader;

import junit.framework.TestCase;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.mailreader.commands.ProfileCheck;
import org.apache.commons.chain.mailreader.commands.Profile;
import org.apache.commons.chain.impl.ContextBase;

public class ProfileCheckTest extends TestCase {

   public void testProfileCheckNeed() {[TODO:]

        Context context = new ContextBase();
        Command command = new ProfileCheck();
        try {
            command.execute(context);
        } catch (Exception e) {
            fail(e.getMessage());
        }

        Profile profile = (Profile) context.get(Profile.PROFILE_KEY);
        assertNotNull("Missing Profile", profile);

    }</programlisting>
    </example>

    <para>Since we're using a test-first approach, we can't run or even
    compile this class (yet). But we can use the test class to tell us which
    other classes we need to write. The next recipe shows how to create a
    Command.</para>
  </section>

  <section>
    <title>Create a Command</title>

    <para><emphasis>Problem:</emphasis> You need to create a
    <classname>Command</classname> for your application, so that a test of the
    Command will succeed.</para>

    <para><emphasis>Solution:</emphasis> Use the test to tell you what code
    will realize the Command's <glossterm><emphasis>API
    contract</emphasis></glossterm>.</para>

    <para><remark>[Glossary: <emphasis>"API contract</emphasis>"
    entry.]</remark></para>

    <para><emphasis>Discussion:</emphasis> A key reason for using Commands,
    and chains of Commands, is testability. Since Commands are designed to act
    on whatever <classname>Context</classname> they receive, we can create a
    Context with a known state to test our Command. In the preceding recipe,
    we created a test for a <classname>ProfileCheck</classname> command. Let's
    implement that Command so that it passes our test.</para>

    <para>To pass the ProfileCheck test, we need to</para>

    <orderedlist>
      <listitem>
        <para>Retrieve the Profile from the Context, using Profile.PROFILE_KEY
        as the attribute name.</para>
      </listitem>

      <listitem>
        <para>If Profile is NULL, create a Profile and store it in the
        Context.</para>
      </listitem>

      <listitem>
        <para>Return <symbol>false</symbol> or <symbol>true</symbol> to the
        caller.</para>
      </listitem>
    </orderedlist>

    <para>Whether to return <symbol>false</symbol> or <symbol>true</symbol> at
    step 3 is optional. You could choose to return <symbol>true</symbol>,
    since this Command did check the profile. Or, you could decide to return
    <symbol>false</symbol>, so that the Command can be used as part of a
    Chain. The return value controls whether a chain terminates or continues.
    True forces a chain to end. False allows a chain to continue. For now,
    we'll just return <symbol>false</symbol>, so that our Command could be
    used as part of a larger chain of Commands.</para>

    <para>The code implementing our ProfileCheck Command is shown as Example
    2.</para>

    <example>
      <title>A Command to create a Profile, if one doesn't exist.</title>

      <programlisting>package org.apache.commons.chain.mailreader.commands;

import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;

public class ProfileCheck implements Command {

    public boolean newProfile(Context context) { return new Profile(); }

    public boolean execute(Context context) throws Exception {
        Object profile = context.get(Profile.PROFILE_KEY);
        if (null == profile) {
            profile = newProfile(context);
            context.put(Profile.PROFILE_KEY, profile);
        }
        return false;
    }
}</programlisting>
    </example>

    <para>To compile our Command and run our test, we also need a
    <classname>Profile</classname> class. Example 3 shows the simplest
    implementation of Profile that will pass our test.</para>

    <example>
      <title>The simplest Profile class that can possibly work.</title>

      <programlisting>package org.apache.commons.chain.mailreader.commands; 
public class Profile { 
    public static String PROFILE_KEY = "profile"; 
}</programlisting>
    </example>

    <para>Note that we used a separate method to create the Profile object. If
    we buried a call to "new Profile()" in the Execute method, we could not be
    reuse our CheckProfile Command to create specialized Profiles. Using
    helper methods to create objects is known as the
    <glossterm>Factory</glossterm> pattern.</para>

    <para><remark><remark>[Glossary: "Factory pattern"
    entry]</remark></remark></para>

    <para>We should now be able to compile all three classes and run our
    test.</para>

    <para><figure>
        <title>Green bar for org.apache.commons.mailreader.ProfileCheckTest
        [TODO: Screen capture]</title>

        <mediaobject>
          <imageobject>
            <imagedata fileref="???" />
          </imageobject>
        </mediaobject>
      </figure></para>
  </section>

  <section>
    <title>Create a Context</title>

    <para><emphasis>Problem:</emphasis> You want a
    <classname>Context</classname> that is
    <glossterm><emphasis>type-safe</emphasis></glossterm>,
    <glossterm><emphasis>encapsulated</emphasis></glossterm>, or interoperable
    with components that expect <glossterm>JavaBean</glossterm>
    properties.</para>

    <para><remark>[Glossary entry: <emphasis>type-safety</emphasis>,
    <emphasis>encapsulate, JavaBean]</emphasis></remark></para>

    <para><emphasis>Solution:</emphasis> Extend your Context class from
    <classname>ContextBase</classname>, and add whatever JavaBean properties
    you need.</para>

    <para><emphasis>Discussion</emphasis>: Many components already use a
    "context". Each of the various Java Servlet "scopes" have a context
    object. The <productnumber>Apache Velocity</productnumber> product relies
    on a context object. Most operating systems have a list of simple
    "environment" settings that is a "context". These examples all use a "map"
    or "dictionary" style context. These contexts are a simple list of
    entries, where each entry is a key and a value.</para>

    <para>Other components also use what amounts to a context but predefine
    the entries as object properties. The Apache Struts framework is one
    example. Developers can define a JavaBean (or
    "<classname>ActionForm</classname>") to act as the context for a request.
    Some components mix both approaches. The Servlet request and session
    objects expose a Map-style context along with several predefined
    properties. Struts supports a variant of the ActionForm that utilizes a
    Map.</para>

    <para>Architects will often choose a Map-style context because they are
    easy to implement and <emphasis>very</emphasis> easy to extend. Usually,
    developers can add their own entries to a Map-style context at will. Of
    course, as illustrated by figure 6, every engineering decision is a
    trade-off. Maps trade type-safety and encapsulation for flexibility and
    extensibility. Other times, architects will decide to trade flexibility
    for type-safety. Or, we may decide to trade extensibility for
    encapsulation. Often, these decisions are driven by the need to
    interoperate with other components that may expect either a Map or a
    JavaBean.</para>

    <figure>
      <title>Every engineering decision is a trade-off.</title>

      <olink>[:TODO: line art -- (Do it right; Do it soon; Do it cheap: Choose
      any two.)]</olink>
    </figure>

    <para>The Jakarta Commons Chain of Command architects have chosen a
    Map-style context as the default. The Chain Context is nothing but a
    "marker interface" for the standard Java <classname>Map</classname>
    interface.</para>

    <para><example>
        <title>The Context interface is a "marker" interface extending
        Map.</title>

        <para><programlisting>public interface Context extends Map {
}</programlisting></para>
      </example>However, to provide developers with type-safety,
    encapsulation, and interoperability, Chain provides a sophisticated
    <classname>ContextBase</classname> class that also supports JavaBean
    properties.</para>

    <para>If a developer declares a JavaBean property on a subclass of
    ContextBase, this property is automatically used by the Map methods. The
    Map <methodname>get</methodname> and <methodname>put</methodname> methods
    of ContextBase introspect the subclass. If they find a JavaBean property
    named after the key argument, the getter or setter method is called
    instead.</para>

    <para>This bit of wizardry enforces type-safety for any declared
    properties, but developers can still use the context as if it were an
    ordinary Map. If all needed attributes are defined as properties, then a
    ContextBase can interoperate with components that expect a Map and also
    with components that expect a JavaBean -- all at the same time. Everything
    is transparent, and there are no special requirements for the
    caller.</para>

    <para>Let's create a test for a ContextBase subclass to prove the JavaBean
    properties and Map methods are interoperable and type-safe.</para>

    <para>To test the context for interoperability, we'll need to do four
    things:</para>

    <orderedlist>
      <listitem>
        <para>Assign a value to a typed property using a JavaBean
        setter</para>
      </listitem>

      <listitem>
        <para>Retrieve the same value using the Map get method</para>
      </listitem>

      <listitem>
        <para>Assign another value using the Map set method</para>
      </listitem>

      <listitem>
        <para>Retrieve the update value using a JavaBean setter</para>
      </listitem>
    </orderedlist>

    <para>To test the context for type-safety, we will also need to
    <orderedlist>
        <listitem>
          <para>Assign a <classname>String</classname> to a typed property
          using the Map get method</para>
        </listitem>

        <listitem>
          <para>Confirm that the assignation throws a "type mismatch"
          exception</para>
        </listitem>
      </orderedlist></para>

    <para>To write these tests, let's create a context with a
    <emphasis>Locale</emphasis> property for an application named
    "MailReader". The code for our <classname>LocaleValueTest</classname> is
    shown in Example 5.<example>
        <title>LocaleValueTest proves that our context is interoperable and
        type-safe.</title>

        <para><programlisting>package org.apache.commons.mailreader;
import junit.framework.TestCase;
import junit.framework.Assert;
import org.apache.commons.chain.mailreader.MailReader;
import java.util.Locale;

public class LocaleValueTest extends TestCase {

    MailReader context;

    public void setUp() {
        context = new MailReader();
    }

    public void testLocaleSetPropertyGetMap() {
        Locale expected = Locale.CANADA_FRENCH;
        context.setLocale(expected);
        Locale locale = (Locale) context.get(MailReader.LOCALE_KEY);
        Assert.assertNotNull(locale);
        Assert.assertEquals(expected, locale);
    }

    public void testLocalePutMapGetProperty() {
        Locale expected = Locale.ITALIAN;
        context.put(MailReader.LOCALE_KEY, expected);
        Locale locale = context.getLocale();
        Assert.assertNotNull(locale);
        Assert.assertEquals(expected, locale);
    }

    public void testLocaleSetTypedWithStringException() {
        String localeString = Locale.US.toString();
        try {
            context.put(MailReader.LOCALE_KEY, localeString);
            fail("Expected 'argument type mismatch' error");
        } catch (UnsupportedOperationException expected) {
            ;
        }
    }
}</programlisting></para>
      </example>A <classname>MailReader</classname> Context object that passes
    the LocaleValueTest is shown as Example 6.<example>
        <title>The simplest MailReader object that will pass
        LocalValueTest.</title>

        <para><programlisting>package org.apache.commons.chain.mailreader;
import org.apache.commons.chain.impl.ContextBase;
import java.util.Locale;

public class MailReader extends ContextBase {Prop
    public static String LOCALE_KEY = "locale";
    private Locale locale;
    public Locale getLocale() {
        return locale;
    }
    public void setLocale(Locale locale) {
        this.locale = locale;
    }
}</programlisting></para>
      </example>The MailReader object in Example 6 shows how much utility is
    built into ContextBase class. All we had to do was define the property.
    The base class took care of the rest. Of course, there is no free lunch.
    ContextBase has to go through the bother of introspection to tell if an
    attribute has a property or not. The ContextBase code is written to be
    efficient, but if your application can just use a Map-style context, you
    could use the leaner version of a MailReader context shown in Example
    7.<example>
        <title>An even simpler MailReader Context (but that would fail
        LocalValueTest).</title>

        <para><programlisting>package org.apache.commons.chain.mailreader;
import org.apache.commons.chain.Context;
import java.util.Hashmap;

public class MailReader extends Hashmap implements Context {
    public static String LOCALE_KEY = "locale";
}</programlisting></para>
      </example>By extending the stock ContextBase subclass, or rolling your
    own class with a HashMap, you can use whatever type of context is best for
    your own artichtecture.</para>
  </section>

  <section>
    <title>Create a Catalog</title>

    <para><emphasis>Problem:</emphasis> You want to layer your application
    without creating dependencies on <classname>Command</classname> objects
    that exist in different layers.</para>

    <para><emphasis>Solution:</emphasis> Assign each command a logical name so
    that it can be called from a "catalog". A catalog moves dependency on to
    the logical name and away from the Java classname or classnames. The
    caller has a dependency on the catalog but not on the actual Command
    classes.</para>

    <para><emphasis>Discussion:</emphasis> Context and Command objects are
    usually used to join layers of an application together. How can one layer
    call Commands in another layer without creating new dependencies between
    the two layers?</para>

    <para>Interlayer dependencies are a common dilemma in enterprise
    applications. We want to layer our application so that it becomes robust
    and cohesive, but we also need a way for the different layers to interact
    with each other. The Commons Chain package offers a
    <classname>Catalog</classname> object to help solve problems with
    dependencies between layers, as well as between components on the same
    layer.</para>

    <para>A Catalog can be configured through <glossterm>metadata</glossterm>
    (an XML document) and instantiated at application startup. Clients can
    retrieve whatever <classname>Commands</classname> they need from the
    Catalog at runtime. If Commands need to be refactored, new classnames can
    be referenced in the metadata, with zero-changes to the application
    code.</para>

    <para><remark>[Glossary: Add "metadata"<emphasis>
    entry.]</emphasis></remark></para>

    <para>Let's take a look at some code that uses a Catalog. Example 8 shows
    a method that executes a Command from a Catalog stored in a web
    application's servlet context. <example>
        <title>A Catalog stores Commands that an application can lookup and
        execute.</title>

        <para><programlisting>   boolean executeCatalogCommand(Context context, String name, HttpServletRequest request) 
        throws Exception {
    
        ServletContext servletContext = request.getSession().getServletContext();  
        Catalog catalog = (Catalog) servletContext.getAttribute("catalog");
        Command command = catalog.getCommand(name);
        boolean stop = command.execute(context);
        return stop;
        
    } </programlisting></para>
      </example></para>

    <para><remark>[Glossary: Add <emphasis>"type-safety"</emphasis>,
    "<emphasis>encapsulate", "JavaBean" entry.]</emphasis></remark></para>

    <para>Notice that we only pass the name of a Command into the method. Also
    note that we retrieve the Command and pass it the Context without knowing
    the precise type of either object. All references are to the standard
    interfaces.</para>

    <para>Example 9 shows an XML document that can be used to create a
    Catalog, like the one called in Example 8.<example>
        <title>A Catalog can be configured using metadata (an XML
        document).</title>

        <para><programlisting>&lt;?xml version="1.0" ?&gt;
&lt;chains&gt;
  &lt;command 
    name="LocaleChange" 
    className="org.apache.commons.chain.mailreader.commands.LocaleChange"/&gt;
  &lt;command 
    name="LogonUser" 
    className="org.apache.commons.chain.mailreader.commands.LogonUser"/&gt;
&lt;/chains&gt;</programlisting></para>
      </example>The application needs to know the name given to a Command we
    want to execute, but it does not need to know the classname of the
    Command. The Command could also be a <classname>Chain</classname> of
    Commands. We can refactor Commands within the Catalog and make
    zero-changes to the application. For example, we might decide to check for
    a user profile before changing a user's locale setting. If we wanted to
    make running a <classname>CheckProfile</classname> Command part of
    "LocaleChange", we could change the Catalog to make "LocaleChange" a
    Chain. Example 10 shows Catalog metadata where "LocaleChange" is a Chain.
    <example>
        <title>A Catalog can be refactored with zero-changes to the
        application code.</title>

        <para><programlisting>&lt;chains&gt;
 &lt;chain name="LocaleChange"&gt; 
    &lt;command 
      className="org.apache.commons.chain.mailreader.commands.ProfileCheck"/&gt;
    &lt;command 
      className="org.apache.commons.chain.mailreader.commands.LocaleChange"/&gt;
  &lt;/chain&gt;
  &lt;command 
    name="LogonUser" 
    className="org.apache.commons.chain.mailreader.commands.LogonUser"/&gt;
&lt;/chains&gt;</programlisting></para>
      </example></para>

    <para>In the "Create a Command" recipe, we use a factory method to create
    a "Profile" object. If we subclass that Command to create a specialized
    Profile, we can cite the new classname in the Catalog, with zero changes
    to the rest of the application.</para>

    <para>Being able to make quick and easy changes to an application can have
    a big effect on the bottom line. The recurring, annual maintenance cost of
    applications can range between 25% to 50% of the initial development cost
    (Gartner Group, May 2002).</para>
  </section>

  <section>
    <title>Load a Catalog From a Web Application</title>

    <para><emphasis>Problem:</emphasis> You'd like to load a catalog
    automatically when a web application starts.</para>

    <para><emphasis>Solution:</emphasis> Utilize the
    <classname>ChainListener</classname> bundled with the Commons Chain of
    Responsibility Package.</para>

    <para><emphasis>Discussion:</emphasis> A Catalog can be created
    progmatically, using conventional Java statements, or by specifying the
    catalog members as metadata (an XML document). For testing, it can be
    easiest to create a catalog progmatically. For deployment, catalogs are
    much easier to maintain as metadata. The downside of using metadata is
    that it needs to be parsed so that the specified objects can be created.
    Happily, the Common Chain of Responsibility package comes bundled with a
    Listener that can read a Catalog metadata file and create the
    corresponding object graph.</para>

    <para>To use ChainListener in a web application, just add a reference to
    your application's web.xml (yet another metadata document). One such
    reference is shown as Example 11. <example>
        <title>Loading a ChainListener via a web.xml</title>

        <programlisting>    &lt;!-- Commons Chain listener to load catalogs  --&gt;
    &lt;context-param&gt;
        &lt;param-name&gt;org.apache.commons.chain.CONFIG_CLASS_RESOURCE&lt;/param-name&gt;
        &lt;param-value&gt;resources/catalog.xml&lt;/param-value&gt;
    &lt;/context-param&gt;
    &lt;listener&gt;
        &lt;listener-class&gt;org.apache.commons.chain.web.ChainListener&lt;/listener-class&gt;
    &lt;/listener&gt;</programlisting>
      </example>The elements in Example 11 expect that there is a
    "catalog.xml" file stored on the application's classpath under a directory
    named "resources". Usually, this would mean that there is a "resources"
    directory under "WEB-INF/classes". If you are using Maven to build your
    application, Maven can copy metadata files from your source tree to the
    web infrastructure tree automatically. Many teams do the same with custom
    Ant build files. Example 12 shows a fragment of a Maven properties file
    that copies <filename>catalog.xml</filename> from a directory under
    "<filename>src/resources/chain</filename>" to
    "<filename>/WEB-INF/classpath/resources</filename>" under the web
    deployment directory. <example>
        <title>Managing resources in a Maven properties file</title>

        <para><programlisting>&lt;!-- ... --&gt;

    &lt;build&gt;
       &lt;sourceDirectory&gt;src/java&lt;/sourceDirectory&gt;
       &lt;resources&gt;
           &lt;resource&gt;
             &lt;directory&gt;${basedir}/src/resources/chain&lt;/directory&gt;
             &lt;targetPath&gt;resources&lt;/targetPath&gt;
             &lt;includes&gt;
               &lt;include&gt;catalog.xml&lt;/include&gt;
             &lt;/includes&gt;
           &lt;/resource&gt;
       &lt;/resources&gt;
    &lt;/build&gt;

&lt;!-- ... --&gt;</programlisting></para>
      </example></para>

    <para>By default, ChainListener will create an application-scope attribute
    by the name of "catalog".</para>

    <para>The default attribute name can be changed, if needed, You can also
    configure ChainListener to read files from a system path or from a JAR.
    See the JavaDoc for all the configuration details. There is also a
    <classname>ChainServlet</classname> if you are using the Servlet 2.2
    platform.</para>

    <para>Using the default attribute, and given an
    <classname>HttpServletRequest</classname> instance, you can access the
    catalog by coding:</para>

    <para><programlisting>        Catalog catalog = (Catalog) request.getSession().getServletContext().getAttribute("catalog");</programlisting></para>

    <para>Given the catalog, you can execute a command and pass it a context,
    like so:</para>

    <para><programlisting>        Command command = catalog.getCommand(commandName);  
        boolean stop = command.execute(context);</programlisting></para>

    <para>Of course, the hard part is populating the context and determining
    which command we need to run for a given request. That work is often left
    to a Front Controller, like the one implemented by Apache Struts.
    Accordingly, we include a "Call a Command from Struts" recipe In this
    chapter. If you like Controllers, but don't like Struts, there are also
    "Create a Controller" and "Call a Command from a Servlet" recipes.</para>
  </section>

  <section>
    <title>Call a Command From Struts</title>

    <para><emphasis>Problem:</emphasis> You'd like to call Commands from
    within a Struts application.</para>

    <para><emphasis>Solution:</emphasis> Use a CommandAction to call a Command
    named for your ActionForm.</para>

    <para><emphasis>Discussion:</emphasis> As a Front Controller, the Apache
    Struts web application framework has three primary responsibilities.
    <orderedlist>
        <listitem>
          <para>Validate a user request</para>
        </listitem>

        <listitem>
          <para>Process a user request</para>
        </listitem>

        <listitem>
          <para>Create a response to the request</para>
        </listitem>
      </orderedlist>The third item is usually delegated to a server page.
    Struts provides framework-aware components, like JSP tag libraries, to
    encourage developers to use another resource to create the response. In
    this way, Struts needs only to select the resource. The actual response
    creation is handled elsewhere.</para>

    <para>Struts also bundles a component to help validate the user request.
    The Struts Validator utilizes metadata to vet request values and create
    user prompts should validation fail.</para>

    <para>To discharge its responsibility to "Process a user request", Struts
    provides an extension point called the "<classname>Action</classname>"
    class. The Struts Action is a blank slate where developers can do whatever
    is necessary to process the request. Some developers even make JDBC calls
    from Actions, but such practices are discouraged. The Struts best practice
    is for Actions to delegate business and system logic calls to another
    component, such as a <glossterm>business facade</glossterm>. The Struts
    Action passes appropriate values to one or methods on the facade. The
    outcome is used to determine an appropriate response. Often, the outcome
    of an Action is described as either "success " or "failure".</para>

    <para><remark>[Glossary: "Business facade" entry]</remark></para>

    <para>Aside from the blank Action, Struts distributes several "standard"
    Actions, such as the <classname>DispatchAction</classname>. The standard
    Actions are designed to be used several times in different ways within an
    application. To allow reuse of Actions, Struts provides a
    <glossterm>Decorator</glossterm> class called an
    <classname>ActionMapping</classname>. Runtime details can be specified
    through the <classname>ActionMappings</classname>, so that each usage of a
    standard Action can be slightly different.</para>

    <para>To solve the problem of calling a Command from Struts, we can use a
    standard Action to retrieve the Catalog and call the Command. We can
    specify runtime details in the ActionMapping. Our details include which
    set of validations to pass and which CommanIn this chapter, d to
    run.</para>

    <para>In practice, the set of validations we need to pass and the command
    we need to run are closely coupled. In fact, it can be a good practice to
    create a distinct set of validations for each Command. If a Command
    changes, then its validations can change with it, without affecting other
    Commands.</para>

    <para>In Struts, the set of validations is coupled to the ActionForm name.
    The ActionForm name is a logical identifier, separate from the ActionForm
    classname. When you use the Struts Validator, the "form" name for the
    Validations is the same string as the ActionForm "name" specified by the
    ActionMapping. A database guru would call this a 1:1 relation; the
    Validator form name and the ActionForm name are shared keys. If we want
    each Command to have its own set of validations, and it's own
    ActionMapping, it follows that we should use the same "key" throughout.
    The Command name can be the ActionForm name as well as the Validator form
    name.</para>

    <para>Example 13 shows how the names line up in the three metadata files,
    the catalog.xml, the validation.xml, and the struts-config.xml. The token,
    or "key", that links the three files together is "LocaleChange"<example>
        <title>A tale of three metadata files: catalog.xml, validation.xml,
        and struts-config.xml</title>

        <para><programlisting>&lt;!-- catalog.xml --&gt;
&lt;?xml version="1.0" ?&gt;
&lt;chains&gt;
    &lt;command
        name="<emphasis>LocaleChange</emphasis>"
        className="org.apache.commons.chain.mailreader.commands.LocaleChange" /&gt;
&lt;/chains&gt;

&lt;!-- validation.xml --&gt;
&lt;?xml version="1.0" ?&gt;
&lt;!DOCTYPE form-validation PUBLIC
          "-//Apache Software Foundation//DTD Commons Validator Rules Configuration 1.1//ENIn this chapter, "
          "http://jakarta.apache.org/commons/dtds/validator_1_1.dtd"&gt;
&lt;form-validation&gt;
    &lt;formset&gt;
        &lt;form name="<emphasis>LocaleChange</emphasis>"&gt;
            &lt;field property="language" depends="required"&gt;
                &lt;arg0 key="prompt.language"/&gt;
            &lt;/field&gt;
        &lt;/form&gt;
    &lt;/formset&gt;
&lt;/form-validation&gt;

&lt;!-- struts-config.xml --&gt;
&lt;?xml version="1.0" ?&gt;
&lt;!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd"&gt;
&lt;struts-config&gt;
    &lt;form-beans&gt;
        &lt;form-bean
            name="<emphasis>LocaleChange</emphasis>"
            type="org.apache.struts.validator.DynaValidatorForm"&gt;
           &lt;form-property name="language" type="java.lang.String"/&gt;
           &lt;form-property name="country" type="java.lang.String"/&gt;
         &lt;/form-bean&gt;
     &lt;/form-beans&gt;
    &lt;action-mappings&gt;
        &lt;action path="/LocaleChange"
            name="<emphasis>LocaleChange</emphasis>"
            type="org.apache.commons.chain.mailreader.struts.CommandAction"&gt;
        &lt;forward name="success" path="/Welcome.do" /&gt;
        &lt;/action&gt;
    &lt;/action-mappings&gt;
&lt;struts-config&gt;</programlisting></para>
      </example>In Example 13, we used "LocaleChange" for the Command name,
    the validation Form name, and the Action form-bean name. To trigger the
    thread, all we need to do is define a generic Action that will use the
    form-bean name as the Command name. Example 14 shows our
    <classname>CommandAction</classname>. <example>
        <title>The CommandAction links the form-bean name with the Command
        name</title>

        <para><programlisting>package org.apache.commons.chain.mailreader.struts;
import org.apache.commons.chain.Catalog;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;
import org.apache.commons.chain.web.servlet.ServletWebContext;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;as the ActionForm name.
import org.apache.struts.action.ActionMapping;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CommandAction extends Action {

    protected Command getCommand(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        Catalog catalog = (Catalog) request.getSession().getServletContext().getAttribute("catalog");
        String name = mapping.getName();
        Command command = catalog.getCommand(name);
        return command;
    }

    protected Context getContext(ActionMapping mapping,
                                 ActionForm form,
                                 HttpServletRequest request,
                                 HttpServletResponse response) throws Exception {
        ServletContext application = request.getSession().getServletContext();
        Context context = new ServletWebContext(application, request, response);
        return context;
    }

    protected static String SUCCESS = "success";

    protected ActionForward findLocation(ActionMapping mapping, boolean stop) {
        if (stop) return mapping.getInputForward(); // Something failed
        return mapping.findForward(SUCCESS);
    }

    public ActionForward execute(
            ActionMapping mapping,
            ActionForm form,
            HttpServletRequest request,
            HttpServletResponse response)
            throws Exception {
        Command command = getCommand(mapping, form, request, response);
        Context context = getContext(mapping, form, request, response);
        boolean stop = command.execute(context);
        ActionForward location = findLocation(mapping, stop);
        return location;
    }</programlisting></para>
      </example>The entry point to an Action class is the
    <methodname>execute</methodname> method. Our execute method calls
    <methodname>getCommand</methodname> and
    <methodname>getContext</methodname> methods that we have defined to obtain
    the Command from the catalog and to build a Context based on the web
    request. Keeping life simple, we use the
    <classname>ServletWebContext</classname> bundled with Commons Chain.
    Depending on your needs, you might want to define your own specialized
    Context.(See "Create a Context" Recipe.) Our execute method then calls the
    command's <methodname>execute</methodname> method. We pass the return
    value of command.execute to our <methodname>findLocation</methodname>
    method, which determines "success" or "failure".</para>

    <para>Another way to write CommandAction would be to use the ActionMapping
    "<property>parameter</property>" property to indicate the Command name .
    To do that, we'd patch <methodname>getCommand</methodname> to call
    <methodname>mapping.getParameter()</methodname> instead of
    <methodname>getName()</methodname>, like this:<programlisting>  -     String name = mapping.getName();
  +     String name = mapping.getParameter();</programlisting></para>

    <para>(The minus sign means remove, or subtract, the line. The plus sign
    means insert, or add, the line. The Unix patch program follows this
    format.)</para>

    <para><remark>[Glossary: "patch" entry]</remark></para>

    <para>The "parameter" approach in the preceding example lets us name the
    form-beans independently of the Command name. But, a consequence is that
    we have to specify the Command name for each ActionMapping.
    (<emphasis>Bor-ring!</emphasis>) You could also merge the two approaches
    and return the parameter property only when it is used, like
    this:<programlisting>        String name = mapping.getParameter();
  +     if ((null==name) || (name=="")) name = mapping.getName();</programlisting></para>

    <para>Or you could mix and match the two approches, using CommandAction
    when the formbean name and the command name match, and a
    CommandParamterAction, when they do not. Struts allows you to use as many
    Actions, and standard Actions, as you like.</para>

    <para>Note that our Command is expected to do the "custom" work usually
    delegated to the Action. Consequently, we do not need to create an Action
    subclass for each task. We can use one or two standard Actions and have
    them call the appropriate Command class. A set of related tasks (or
    "story") might share an ActionForm class and a Command class, but, most
    often, the Actions can be standard, reusable Actions.</para>

    <para>Something else to note about Example 14 is that we use the
    "LocaleChange" token as the <property>path</property> attribute. This
    means that the story would be trigged by opening (for example) the
    "<filename>/LocaleChange.do</filename>" page. Even so, the path is
    <emphasis>not</emphasis> part of our <glossterm>semantic
    chain</glossterm>. The path is not a fully logical name that we control.
    The path token is shared with the container, and the container may have
    its own constraints on the path. (JAAS pattern matching, for example.) The
    path can't be part of our chain of keys, since it is shared with the
    container's "business logic".</para>

    <para><remark>[Glossary: <emphasis>Add "Semantic chain pattern"</emphasis>
    entry.]</remark></para>

    <para>Having used "LocaleChange" for everything else, using it for the
    path token seems natural. Most of us would do the same. But, the path can
    vary as needed, without upsetting the rest of the semantic chain. If the
    "path" needs to change to suit a change in the JAAS configuration, nothing
    else needs to change.</para>

    <para>Of course, there would be several other ways to call a Command from
    a Struts Action. Since the request is passed to the Action, it's easy to
    obtain a Catalog stored in application scope. Once you have access to the
    Catalog, the rest is easy.</para>

    <para>Other frameworks, like WebWorks and Maverick, have components
    similar to Struts Actions. Any of these components can be used to create a
    Context, access the Catalog, and execute a Command.</para>
  </section>

  <section>
    <title>Create a Controller</title>

    <para><emphasis>Problem:</emphasis> You want to base your application's
    <glossterm>Controller</glossterm> components on the Commons Chain of
    Command package.</para>

    <para><remark>[Glossary: <emphasis>Add "Controller pattern"</emphasis>
    entry, along with Application Controller and Front
    Controller.]</remark></para>

    <para><emphasis>Solution:</emphasis> Create a set of interfaces for a
    Controller package that can be implemented using base classes from the
    Chain of Command package.</para>

    <para><emphasis>Warning: Since we are creating a base package, this recipe
    is longer than most. Each individual component is simple enough, but there
    are several components to cover. Since the components are interrelated,
    covering them separately would be confusing. So, sit back, loosen your
    belt, and enjoy, while we whip up a "seven-course meal".</emphasis></para>

    <para><emphasis>Discussion:</emphasis> Many applications use
    implementations of the Controller pattern to field user requests.
    <productname>Core J2EE Patterns: Best Practices and Design
    Strategies</productname> <productnumber>[ISBN:
    0-13-142246-4]</productnumber> describes a controller as a component that
    "interacts with a client, controlling and managing the handling of each
    request." There are several flavors of controllers, including Application
    Controllers and Front Controllers. Many web application frameworks, like
    Apache Struts, utilize a Front Controller.</para>

    <para>Often, an implementation of the Controller pattern will in turn use
    the Command pattern or Chain of Command pattern. How can we use the
    Commons Chain of Command package to implement a Controller?</para>

    <para>Following the general description from Core J2EE Patterns, let's
    start by defining a test that passes a request to a controller and
    confirms that an appropriate response is returned.</para>

    <para>To write our test, we need to:<orderedlist>
        <listitem>
          <para>Create a Controller.</para>
        </listitem>

        <listitem>
          <para>Add a Handler for our Request to the Controller.</para>
        </listitem>

        <listitem>
          <para>Create a Request and pass it to the Controller.</para>
        </listitem>

        <listitem>
          <para>Confirm that the Request returns the expected Response.</para>
        </listitem>
      </orderedlist></para>

    <para>To simplify writing the test, lets make a few executive
    decisions:</para>

    <orderedlist>
      <listitem>
        <para>The Request and Response object have "name" properties.</para>
      </listitem>

      <listitem>
        <para>The name of a Response matches the name of its Request (a shared
        key).</para>
      </listitem>

      <listitem>
        <para>The test will be based on interfaces; implemented classes will
        extend Common Chain members.</para>
      </listitem>

      <listitem>
        <para>The Controller extends Catalog.</para>
      </listitem>

      <listitem>
        <para>The Request and Response extend Context.</para>
      </listitem>

      <listitem>
        <para>The Request Handler extends Command.</para>
      </listitem>

      <listitem>
        <para>For no particular reason, we'll call our controller package
        "Agility".</para>
      </listitem>
    </orderedlist>

    <para>Example 15 shows a <classname>ProcessingTest</classname> class with
    our <methodname>testRequestResponseNames</methodname> method.<example>
        <title>Test to assert that our Controller can process a Request and
        return an appropriate Response</title>

        <para><programlisting>package org.apache.commons.agility;

import junit.framework.TestCase; 
import org.apache.commons.agility.impl.ControllerCatalog;
import org.apache.commons.agility.impl.HandlerCommand;
import org.apache.commons.agility.impl.RequestContext;

public class ProcessingTest extends TestCase {

    public void testRequestResponseName() {
        
        String NAME = "TestProcessing"; 

        Controller controller = new ControllerCatalog();

        RequestHandler handler = new HandlerCommand(NAME);
        controller.addHandler(handler);
        Request request = new RequestContext(NAME);
        controller.process(request);
        Response response = request.getResponse();

        assertNotNull(response);
        assertEquals(NAME, response.getName());
    }
}</programlisting></para>
      </example>To compile the ProcessingTest class, we will need interface
    members for <classname>Controller</classname>,
    <classname>RequestHandler</classname>, <classname>Request</classname>, and
    <classname>Response</classname>, and class members for
    <classname>ControllerCatalog</classname>,
    <classname>HandlerCommand</classname>, and
    <classname>RequestContext</classname>. Figure 7 shows the UML for the four
    interfaces.<figure>
        <title>The four interfaces needed to realize ProcessingTest</title>

        <olink><remark>[TODO: UML for Controller, RequestHandler, Request, and
        Response ]</remark></olink>
      </figure></para>

    <para>Referring to the UML in Figure 7, we can write the code for our
    interface members, as shown in Example 16. <example>
        <title>To compile ProcessTest, we need to define four
        interfaces.</title>

        <para><programlisting>// Controller.java
package org.apache.commons.agility;
public interface Controller {
    void addHandler(RequestHandler handler);
    RequestHandler getHandler(String name) throws ProcessException;
    void process(Request request) throws ProcessException;
}

// Request.java
package org.apache.commons.agility;
public interface Request {
    String getName();
    Response getResponse();
    void setResponse(Response response);
}

// Response.java
package org.apache.commons.agility;
public interface Response {
    String getName();
}

// RequestHandler.java
package org.apache.commons.agility;
public interface RequestHandler {
    String getName();
    void handle(Request request) throws ProcessException;
}

// ProcessException.java
package org.apache.commons.agility;
public class ProcessException extends Exception {
    public ProcessException(Throwable cause) {
        super(cause);
    }
}</programlisting></para>
      </example></para>

    <para>With the interfaces out of the way, we can turn to the classes we
    need to implement. The UML for the class members we need is shown as
    Figure 8. <figure>
        <title>The thee classes needed to realize ProcessingTest.</title>

        <olink><remark>[TODO: UML for ControllerCatalog, RequestContext, and
        HandlerCommand.]</remark></olink>
      </figure></para>

    <para>If we create the classes indicated by Figure 8, and stub-out the
    methods, we can get the code to compile. The test will run, but skeleton
    classes won't pass muster. Let's implement each class, starting with
    HandlerCommand, which is shown as Example 17.</para>

    <para><example>
        <title>HandlerCommand provides default behavior that subclasses can
        override</title>

        <para><programlisting>package org.apache.commons.agility.impl;

import org.apache.commons.agility.ProcessException;
import org.apache.commons.agility.Request;
import org.apache.commons.agility.RequestHandler;
import org.apache.commons.agility.Response;
import org.apache.commons.chain.Command;
import org.apache.commons.chain.Context;

public class HandlerCommand implements Command, RequestHandler {
    String name =  null;

    public HandlerCommand(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public boolean execute(Context context) throws Exception {
        handle((Request) context);
        return true;
    }

    public void handle(Request request) throws ProcessException {
        try {
            String name = request.getName();
            Response response = new ResponseContext(name);
            request.setResponse(response);
        } catch (Exception e) {
            throw new ProcessException(e);
        }
    }
}</programlisting></para>
      </example>The <methodname>handle(Request)</methodname> method of
    HandlerCommand realizes the prime responsibility for this class: create a
    Response for the Request. The execute(Context) method is an
    <glossterm>adapter</glossterm> that delegates to the handle method. Now we
    can call execute or handle and achieve the same result. The constructor
    assigns each instance of HandlerCommand a name so that it can be matched
    with a Request.</para>

    <para><remark><remark>[Glossary: "apapter pattern"
    entry]</remark></remark></para>

    <para>The handle(Request) method shown here is not very useful. However,
    it will pass our test and prove the infrastructure is working. Subclasses
    can override handle(Request) to create the appropriate Response for a
    given Request. Since HandlerCommands are still Commands, we can itemize
    our HandlerCommand subclasses as metadata (an XML document). This will
    make it easy to handle new Requests as our application grows.</para>

    <para>The HandlerCommand class creates a ResponseContext instance and sets
    it as the Response. The ResponseContext class is shown as Example
    18.</para>

    <para><example>
        <title>Many other implementations of ResponseContext are possible.
        They just need to implement Response and extend ContextBase.</title>

        <para><programlisting>package org.apache.commons.agility.impl;

import org.apache.commons.agility.Response;
import org.apache.commons.chain.impl.ContextBase;

public class ResponseContext extends ContextBase implements Response {

    private String name;

    public ResponseContext(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }
}</programlisting></para>
      </example>Since we're just testing the infrastructure, our
    ResponseContext is rudimentary. A Front Controller for a web application
    framework might define several attributes for a Response, such as the
    location of a server page. The RequestHandler can create any kind of
    Response object that might be needed.</para>

    <para>Whatever RequestHandlers we need are added to the Catalog, either as
    metadata or programatically. Our tests add the handler programatically, so
    we need to implement the AddHandler method. Example 19 shows our
    implementation of CatalogController. <example>
        <title>RequestHandlers can be added to the CatalogController
        programatically or through metadata</title>

        <para><programlisting>package org.apache.commons.agility.impl;

import org.apache.commons.agility.Controller;
import org.apache.commons.agility.ProcessException;
import org.apache.commons.agility.Request;
import org.apache.commons.agility.RequestHandler;
import org.apache.commons.chain.impl.CatalogBase;
import org.apache.commons.chain.Command;

public class ControllerCatalog extends CatalogBase implements Controller {
    public RequestHandler getHandler(String name) {
        return (RequestHandler) getCommand(request.getName());
    }

    public void addHandler(RequestHandler handler) {
        this.addCommand(handler.getName(), (Command) handler);
    }

    public void process(Request request) throws ProcessException {
        Handler handler = getHandler(request.getName());
        if (handler != null) handler.handle(request);
    }
}</programlisting></para>
      </example>The main entry point to our Controller is the
    <methodname>process(Request)</methodname> method. This method could host a
    great deal of functionality. We could even implement the process method as
    a series of Commands or Chains of Commands. An application could then
    fine-tune the request processing by specifying different Commands in a
    metadata catalog. The Struts web application framework uses this approach
    for its request processor.</para>

    <para>But for now, we just want to pass our test. All the process method
    needs to do is find the RequestHandler and call its handle(Request)
    method. We can do that just by looking up the name of the Request in our
    catalog and retrieving the matching RequestHandler (or Command).</para>

    <para>The <methodname>addHandler(RequestHandler)</methodname> method is
    another adapter that delegates to an inherited method. In this case,
    addHandler calls <methodname>addCommand(String,Command)</methodname>.
    Since our RequestHandlers are Commands, they can be passed to the
    superclass method. The <methodname>getHandler(String)</methodname> method
    is yet another adapter/delegate.</para>

    <para>Last but not least is the RequestContext class, shown as Example
    20.</para>

    <para><example>
        <title>RequestContext ties it all together</title>

        <para><programlisting>package org.apache.commons.agility.impl;

import org.apache.commons.agility.Request;
import org.apache.commons.agility.Response;
import org.apache.commons.chain.impl.ContextBase;

public class RequestContext extends ContextBase implements Request {

    private String name;
    private Response response;

    public RequestContext(String name) {
        super();
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public Response getResponse() {
        return response;
    }

    public void setResponse(Response response) {
        this.response = response;
    }
}</programlisting></para>
      </example>Like the ResponseContext, an application could add several
    properties to its Request class. A web application might wrap or transfer
    attributes from the HttpServletRequest. But so long as the class
    implements Request and Context, it will plug into our Controller
    implementation.</para>

    <para>Using the interfaces and base classes shown here, you can create
    whatever Controllers you need.</para>
  </section>

  <section>
    <title>Call a Command From a Servlet</title>

    <para><emphasis>Problem:</emphasis> You would like to call commands during
    your application using a servlet.</para>

    <para><emphasis>Solution:</emphasis> Use the Listener from the "Load a
    Catalog from a Web Application" recipe to setup a list of Commands, and
    the Controller from the "Create a Controller" recipe to process the
    request.</para>

    <para><emphasis>Discussion: [<remark>TODO:]</remark></emphasis></para>

    <para>###</para>
  </section>
</article>