<?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.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 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.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>
