<?xml version="1.0" encoding="UTF-8"?>
<!--
   Licensed to the Apache Software Foundation (ASF) under one or more
   contributor license agreements.  See the NOTICE file distributed with
   this work for additional information regarding copyright ownership.
   The ASF licenses this file to You under the Apache License, Version 2.0
   (the "License"); you may not use this file except in compliance with
   the License.  You may obtain a copy of the License at
  
        http://www.apache.org/licenses/LICENSE-2.0
  
   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
-->
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
<article>
  <title>Apache 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 Apache Commons [<link
    linkend="???">http://commons.apache.org/</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.chain2.Command;
import org.apache.commons.chain2.Context;
import org.apache.commons.chain2.mailreader.commands.ProfileCheck;
import org.apache.commons.chain2.mailreader.commands.Profile;
import org.apache.commons.chain2.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.chain2.mailreader.commands;

import org.apache.commons.chain2.Command;
import org.apache.commons.chain2.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.chain2.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 Apache 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.chain2.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.chain2.mailreader;
import org.apache.commons.chain2.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.chain2.mailreader;
import org.apache.commons.chain2.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.chain2.mailreader.commands.LocaleChange"/&gt;
  &lt;command 
    name="LogonUser" 
    className="org.apache.commons.chain2.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.chain2.mailreader.commands.ProfileCheck"/&gt;
    &lt;command 
      className="org.apache.commons.chain2.mailreader.commands.LocaleChange"/&gt;
  &lt;/chain&gt;
  &lt;command 
    name="LogonUser" 
    className="org.apache.commons.chain2.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.chain2.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.chain2.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.chain2.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.chain2.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.chain2.mailreader.struts;
import org.apache.commons.chain2.Catalog;
import org.apache.commons.chain2.Command;
import org.apache.commons.chain2.Context;
import org.apache.commons.chain2.web.servlet.ServletWebContextBase;
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.chain2.Command;
import org.apache.commons.chain2.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.chain2.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.chain2.impl.CatalogBase;
import org.apache.commons.chain2.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.chain2.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>
