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

<document>

  <properties>
    <title>Cookbook</title>
    <author email="husted@apache.org">Ted Husted</author>
    <author email="martinc@apache.org">Martin Cooper</author>
  </properties>

  <body>

  <section name="Introduction">

    <p>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.</p>

    <p>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, if 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 processing might need to halt.</p>

    <p>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 elegance, we must organize
    complex, multi-step processes so that they are easy to discover and
    change.</p>

    <!-- p><remark>[TODO:]</remark></p -->
  </section>

  <section name='Separate "business" logic from "presentation" logic'>

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

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

    <p><em>Discussion</em>: 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?</p>

    <p>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.</p>

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

    <!-- 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 -->

    <p>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
    business logic in the middle of a web command from
    other necessary tasks that are part of the request/response
    transaction.</p>

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

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

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

    <p>The <em>Chain of Responsibility</em> package combines the
    Command pattern with the classic Chain of Responsibility
    pattern to make it easy to call a business command as part of
    a larger application command. (For more about the patterns, see
    <em>Design Patterns: Elements of Reusable Object Orientated
    Software</em> [ISBN 0-201-63361-2]).</p>

    <!-- p><remark><remark>[Glossary: "Chain of Responsibility pattern"
    entry]</remark></remark></p -->

    <!-- p><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></p -->

    <p>To implement the patterns, the <code>Chain</code> package
    defines five key interfaces:</p>

    <ul>
      <li>Context</li>

      <li>Command</li>

      <li>Chain</li>

      <li>Filter</li>

      <li>Catalog</li>
    </ul>

    <p><em>Context.</em> A <code>Context</code>
    represents the state of an application. In the Chain package,
    <code>Context</code> is a marker interface for a
    <code>java.util.Map</code>. 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.</p>

    <p><em>Command.</em> A <code>Command</code>
    represents a unit of work. A Command has a single
    entry method: <code>public boolean execute(Context
    context)</code>. 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 <code>true</code>, then
    other Commands in a Chain should <em>not</em> be executed. If
    a Command returns <code>false</code>, then other Commands in the Chain
    (if any) may execute.</p>

    <!-- p><remark><remark>[Glossary: "unit of work"
    entry]</remark></remark></p -->

    <p><em>Chain.</em> <code>Chain</code> implements
    the <code>Command</code> interface, so a
    <code>Chain</code> can be used interchangeably with a
    <code>Command</code>. 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 <em>Liskov substitution principle.
    </em></p>

    <!-- p><em><remark>[Glossary: "Liskov substitution
    principle" entry]</remark></em></p -->

    <p><em>Filter.</em> 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
    <code>Filter</code> is a specialized
    <code>Command</code> that adds a
    <code>postProcess</code> method. A
    <code>Chain</code> is expected to call the
    <code>postProcess</code> method of any filters in the chain
    before returning. A Command that implements Filter can safely release any
    resources it allocated through the <code>postProcess</code>
    method, even if those resources are shared with other Commands.</p>

    <p><em>Catalog.</em> 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 <code>Catalog</code> is a
    collection of logically named Commands (or Chains) that a client can
    execute, without knowing the Command's classname.</p>

    <!-- p><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></p -->

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

  <section name="Test a Command">

    <p><em>Problem:</em> You want to start using
    <code>Command</code> objects in your application.</p>

    <p><em>Solution:</em> Use Test Driven
    Development 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.</p>

    <!-- p><em><remark>[Glossary: "Test Driven
    Development" entry]</remark></em></p -->

    <p><em>Discussion: </em>Let's say we're working on an
    application that maintains a "<code>Profile</code>" 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.</p>

    <p>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.</p>

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

    <ol>
      <li>
        <p>Create a Context with a known state</p>
      </li>

      <li>
        <p>Create a Command instance to test</p>
      </li>

      <li>
        <p>Execute the Command, passing our Context</p>
      </li>

      <li>
        <p>Confirm that our Context now contains the expected state</p>
      </li>
    </ol>

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

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

      <source><![CDATA[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() {

        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);

    }]]></source>
    </example>

    <p>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.</p>
  </section>

  <section name="Create a Command">

    <p><em>Problem:</em> You need to create a
    <code>Command</code> for your application, so that a test of the
    Command will succeed.</p>

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

    <!-- p><remark>[Glossary: <em>"API contract</em>"
    entry.]</remark></p -->

    <p><em>Discussion:</em> A key reason for using Commands,
    and chains of Commands, is testability. Since Commands are designed to act
    on whatever <code>Context</code> 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 <code>ProfileCheck</code> command. Let's
    implement that Command so that it passes our test.</p>

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

    <ol>
      <li>
        <p>Retrieve the Profile from the Context, using Profile.PROFILE_KEY
        as the attribute name.</p>
      </li>

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

      <li>
        <p>Return <code>false</code> or <code>true</code> to the
        caller.</p>
      </li>
    </ol>

    <p>Whether to return <code>false</code> or <code>true</code> at
    step 3 is optional. You could choose to return <code>true</code>,
    since this Command did check the profile. Or, you could decide to return
    <code>false</code>, 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 <code>false</code>, so that our Command could be
    used as part of a larger chain of Commands.</p>

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

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

      <source><![CDATA[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 Profile 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;
    }
}]]></source>
    </example>

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

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

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

    <p>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
    reuse our CheckProfile Command to create specialized Profiles. Using
    helper methods to create objects is known as the
    Factory pattern.</p>

    <!-- p><remark><remark>[Glossary: "Factory pattern"
    entry]</remark></remark></p -->

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

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

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

  <section name="Create a Context">

    <p><em>Problem:</em> You want a
    <code>Context</code> that is
    <em>type-safe</em>,
    <em>encapsulated</em>, or interoperable
    with components that expect JavaBean
    properties.</p>

    <!-- p><remark>[Glossary entry: <em>type-safety</em>,
    <em>encapsulate, JavaBean]</em></remark></p -->

    <p><em>Solution:</em> Extend your Context class from
    <code>ContextBase</code>, and add whatever JavaBean properties
    you need.</p>

    <p><em>Discussion</em>: 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.</p>

    <p>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
    "<code>ActionForm</code>") 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.</p>

    <p>Architects will often choose a Map-style context because they are
    easy to implement and <em>very</em> 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.</p>

    <!-- 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 -->

    <p>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 <code>Map</code>
    interface.</p>

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

        <p><source><![CDATA[public interface Context extends Map {
}]]></source></p>
      </example>However, to provide developers with type-safety,
    encapsulation, and interoperability, Chain provides a sophisticated
    <code>ContextBase</code> class that also supports JavaBean
    properties.</p>

    <p>If a developer declares a JavaBean property on a subclass of
    ContextBase, this property is automatically used by the Map methods. The
    Map <code>get</code> and <code>put</code> 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.</p>

    <p>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.</p>

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

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

    <ol>
      <li>
        <p>Assign a value to a typed property using a JavaBean
        setter</p>
      </li>

      <li>
        <p>Retrieve the same value using the Map get method</p>
      </li>

      <li>
        <p>Assign another value using the Map set method</p>
      </li>

      <li>
        <p>Retrieve the update value using a JavaBean setter</p>
      </li>
    </ol>

    <p>To test the context for type-safety, we will also need to
    <ol>
        <li>
          <p>Assign a <code>String</code> to a typed property
          using the Map get method</p>
        </li>

        <li>
          <p>Confirm that the assignation throws a "type mismatch"
          exception</p>
        </li>
      </ol></p>

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

        <p><source><![CDATA[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) {
            ;
        }
    }
}]]></source></p>
      </example>A <code>MailReader</code> Context object that passes
    the LocaleValueTest is shown <!-- as Example 6 --> below.<example>
        <title>The simplest MailReader object that will pass
        LocalValueTest.</title>

        <p><source><![CDATA[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;
    }
}]]></source></p>
      </example>The MailReader object <!-- in Example 6 --> above 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 --> below.<example>
        <title>An even simpler MailReader Context (but that would fail
        LocalValueTest).</title>

        <p><source><![CDATA[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";
}]]></source></p>
      </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.</p>
  </section>

  <section name="Create a Catalog">

    <p><em>Problem:</em> You want to layer your application
    without creating dependencies on <code>Command</code> objects
    that exist in different layers.</p>

    <p><em>Solution:</em> 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.</p>

    <p><em>Discussion:</em> 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?</p>

    <p>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
    <code>Catalog</code> object to help solve problems with
    dependencies between layers, as well as between components on the same
    layer.</p>

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

    <!-- p><remark>[Glossary: Add "metadata"<em>
    entry.]</em></remark></p -->

    <p>Let's take a look at some code that uses a Catalog. <!-- Example 8 shows --> Shown below is
    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>

        <p><source><![CDATA[   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;
        
    } ]]></source></p>
      </example></p>

    <!-- p><remark>[Glossary: Add <em>"type-safety"</em>,
    "<em>encapsulate", "JavaBean" entry.]</em></remark></p -->

    <p>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.</p>

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

        <p><source><![CDATA[<?xml version="1.0" ?>
<catalog>
  <command 
    name="LocaleChange" 
    className="org.apache.commons.chain.mailreader.commands.LocaleChange"/>
  <command 
    name="LogonUser" 
    className="org.apache.commons.chain.mailreader.commands.LogonUser"/>
</catalog>]]></source></p>
      </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 <code>Chain</code> 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 <code>CheckProfile</code> Command part of
    "LocaleChange", we could change the Catalog to make "LocaleChange" a
    Chain. <!-- Example 10 --> The following example shows Catalog metadata where "LocaleChange" is a Chain.
    <example>
        <title>A Catalog can be refactored with zero-changes to the
        application code.</title>

        <p><source><![CDATA[<catalog>
  <chain name="LocaleChange">
    <command 
      className="org.apache.commons.chain.mailreader.commands.ProfileCheck"/>
    <command 
      className="org.apache.commons.chain.mailreader.commands.LocaleChange"/>
  </chain>
  <command 
    name="LogonUser" 
    className="org.apache.commons.chain.mailreader.commands.LogonUser"/>
</catalog>]]></source></p>
      </example></p>

    <p>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.</p>

    <p>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).</p>
  </section>

  <section name="Load a Catalog From a Web Application">

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

    <p><em>Solution:</em> Utilize the
    <code>ChainListener</code> bundled with the Commons Chain of
    Responsibility Package.</p>

    <p><em>Discussion:</em> 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 programatically. 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 Commons Chain of Responsibility package comes bundled with a
    Listener that can read a Catalog metadata file and create the
    corresponding object graph.</p>

    <p>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 --> below. <example>
        <title>Loading a ChainListener via a web.xml</title>

        <source><![CDATA[<!-- Commons Chain listener to load catalogs  -->
<context-param>
  <param-name>org.apache.commons.chain.CONFIG_CLASS_RESOURCE</param-name>
  <param-value>resources/catalog.xml</param-value>
</context-param>
<listener>
  <listener-class>org.apache.commons.chain.web.ChainListener</listener-class>
</listener>]]></source>
      </example></p>
    <p>The elements in <!-- Example 11 --> this example 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 --> Shown below is a fragment of a Maven properties file
    that copies <code>catalog.xml</code> from a directory under
    "<code>src/resources/chain</code>" to
    "<code>/WEB-INF/classpath/resources</code>" under the web
    deployment directory. <example>
        <title>Managing resources in a Maven properties file</title>

        <p><source><![CDATA[<!-- ... -->

<build>
  <sourceDirectory>src/java</sourceDirectory>
  <resources>
    <resource>
      <directory>${basedir}/src/resources/chain</directory>
      <targetPath>resources</targetPath>
      <includes>
        <include>catalog.xml</include>
      </includes>
    </resource>
  </resources>
</build>

<!-- ... -->]]></source></p>
      </example></p>

    <p>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 <code>ChainServlet</code> if you are using the Servlet 2.2
    platform.</p>

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

    <p><source><![CDATA[Catalog catalog = (Catalog) request.getSession()
        .getServletContext().getAttribute("catalog");]]></source></p>

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

    <p><source><![CDATA[Command command = catalog.getCommand(commandName);  
    boolean stop = command.execute(context);]]></source></p>

    <p>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.</p>
  </section>

  <section name="Call a Command From Struts">

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

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

    <p><em>Discussion:</em> As a Front Controller, the Apache
    Struts web application framework has three primary responsibilities.
    <ol>
        <li>
          <p>Validate a user request</p>
        </li>

        <li>
          <p>Process a user request</p>
        </li>

        <li>
          <p>Create a response to the request</p>
        </li>
      </ol>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.</p>

    <p>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.</p>

    <p>To discharge its responsibility to "Process a user request", Struts
    provides an extension point called the "<code>Action</code>"
    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 business facade. 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".</p>

    <!-- p><remark>[Glossary: "Business facade" entry]</remark></p -->

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

    <p>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 Command to
    run.</p>

    <p>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.</p>

    <p>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.</p>

    <p><!-- Example 13 --> The following example 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>

        <p><source><![CDATA[<!-- catalog.xml -->
<?xml version="1.0" ?>
<catalog>
    <command
        name="<em>LocaleChange</em>"
        className="org.apache.commons.chain.mailreader.commands.LocaleChange" />
</catalog>

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

<!-- struts-config.xml -->
<?xml version="1.0" ?>
<!DOCTYPE struts-config PUBLIC
          "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
          "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
    <form-beans>
        <form-bean
            name="<em>LocaleChange</em>"
            type="org.apache.struts.validator.DynaValidatorForm">
           <form-property name="language" type="java.lang.String"/>
           <form-property name="country" type="java.lang.String"/>
         </form-bean>
     </form-beans>
    <action-mappings>
        <action path="/LocaleChange"
            name="<em>LocaleChange</em>"
            type="org.apache.commons.chain.mailreader.struts.CommandAction">
        <forward name="success" path="/Welcome.do" />
        </action>
    </action-mappings>
<struts-config>]]></source></p>
      </example>In <!-- Example 13 --> the above example, 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 --> The example below shows our
    <code>CommandAction</code>. <example>
        <title>The CommandAction links the form-bean name with the Command
        name</title>

        <p><source><![CDATA[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;
    }]]></source></p>
      </example>The entry point to an Action class is the
    <code>execute</code> method. Our execute method calls
    <code>getCommand</code> and
    <code>getContext</code> 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
    <code>ServletWebContext</code> 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 <code>execute</code> method. We pass the return
    value of command.execute to our <code>findLocation</code>
    method, which determines "success" or "failure".</p>

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

    <p>(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.)</p>

    <!-- p><remark>[Glossary: "patch" entry]</remark></p -->

    <p>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.
    (<em>Bor-ring!</em>) You could also merge the two approaches
    and return the parameter property only when it is used, like
    this:<source><![CDATA[        String name = mapping.getParameter();
  +     if ((null==name) || (name=="")) name = mapping.getName();]]></source></p>

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

    <p>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.</p>

    <p>Something else to note about <!-- Example 14 --> the above example 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
    <em>not</em> part of our semantic
    chain. 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".</p>

    <!-- p><remark>[Glossary: <em>Add "Semantic chain pattern"</em>
    entry.]</remark></p -->

    <p>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.</p>

    <p>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.</p>

    <p>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.</p>
  </section>

  <section name="Create a Controller">

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

    <!-- p><remark>[Glossary: <em>Add "Controller pattern"</em>
    entry, along with Application Controller and Front
    Controller.]</remark></p -->

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

    <p><em>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".</em></p>

    <p><em>Discussion:</em> Many applications use
    implementations of the Controller pattern to field user requests.
    <em>Core J2EE Patterns: Best Practices and Design
    Strategies</em> [ISBN 0-13-142246-4] 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.</p>

    <p>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?</p>

    <p>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.</p>

    <p>To write our test, we need to:<ol>
        <li>
          <p>Create a Controller.</p>
        </li>

        <li>
          <p>Add a Handler for our Request to the Controller.</p>
        </li>

        <li>
          <p>Create a Request and pass it to the Controller.</p>
        </li>

        <li>
          <p>Confirm that the Request returns the expected Response.</p>
        </li>
      </ol></p>

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

    <ol>
      <li>
        <p>The Request and Response object have "name" properties.</p>
      </li>

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

      <li>
        <p>The test will be based on interfaces; implemented classes will
        extend Commons Chain members.</p>
      </li>

      <li>
        <p>The Controller extends Catalog.</p>
      </li>

      <li>
        <p>The Request and Response extend Context.</p>
      </li>

      <li>
        <p>The Request Handler extends Command.</p>
      </li>

      <li>
        <p>For no particular reason, we'll call our controller package
        "Agility".</p>
      </li>
    </ol>

    <p><!-- Example 15 --> The following example shows a <code>ProcessingTest</code> class with
    our <code>testRequestResponseNames</code> method.<example>
        <title>Test to assert that our Controller can process a Request and
        return an appropriate Response</title>

        <p><source><![CDATA[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());
    }
}]]></source></p>
      </example>To compile the ProcessingTest class, we will need interface
    members for <code>Controller</code>,
    <code>RequestHandler</code>, <code>Request</code>, and
    <code>Response</code>, and class members for
    <code>ControllerCatalog</code>,
    <code>HandlerCommand</code>, and
    <code>RequestContext</code>. <!-- 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></p>

    <p><!-- 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>

        <p><source><![CDATA[// 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);
    }
}]]></source></p>
      </example></p>

    <p>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></p>

    <p>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 --> below.</p>

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

        <p><source><![CDATA[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);
        }
    }
}]]></source></p>
      </example>The <code>handle(Request)</code> method of
    HandlerCommand realizes the prime responsibility for this class: create a
    Response for the Request. The execute(Context) method is an
    adapter 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.</p>

    <!-- p><remark><remark>[Glossary: "apapter pattern"
    entry]</remark></remark></p -->

    <p>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.</p>

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

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

        <p><source><![CDATA[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;
    }
}]]></source></p>
      </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.</p>

    <p>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 --> The following shows our
    implementation of CatalogController. <example>
        <title>RequestHandlers can be added to the CatalogController
        programatically or through metadata</title>

        <p><source><![CDATA[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);
    }
}]]></source></p>
      </example>The main entry point to our Controller is the
    <code>process(Request)</code> 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.</p>

    <p>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).</p>

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

    <p>Last but not least is the RequestContext class, shown <!-- as Example
    20 --> below.</p>

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

        <p><source><![CDATA[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;
    }
}]]></source></p>
      </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.</p>

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

  <section name="Call a Command From a Servlet">

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

    <p><em>Solution:</em> 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.</p>

    <p><em>Discussion: [<remark>TODO:]</remark></em></p>

  </section>

  </body>
</document>
