| <html> |
| <head> |
| <title>Proposal for "Chain of Responsibility" Package</title> |
| </head> |
| <body bgcolor="white"> |
| |
| <div align="center"> |
| <h1>Proposal for <em>Chain of Responsibility</em> Package</h1> |
| </div> |
| |
| <h3>(0) Rationale</h3> |
| |
| <p>A popular technique for organizing the execution of complex processing |
| flows is the "Chain of Responsibility" pattern, as described (among many |
| other places) in the classic "Gang of Four" design patterns book. Although |
| the fundamental API contracts required to implement this design patten are |
| extremely simple, it is useful to have a base API that facilitates using |
| the pattern, and (more importantly) encouraging composition of command |
| implementations from multiple diverse sources.</p> |
| |
| <p>Towards that end, the proposed API models a computation as a series of |
| "commands" that can be combined into a "chain". The API for a command |
| consists of a single method (<code>execute()</code>), which is passed a |
| "context" parameter containing the dynamic state of the computation, and |
| whose return value is a boolean that determines whether or not processing |
| for the current chain has been completed (true), or whether processing |
| should be delegated to the next command in the chain (false).</p> |
| |
| <p>The "context" abstraction is designed to isolate command implementations |
| from the environment in which they are run (such as a command that can be |
| used in either a Servlet or Portlet, without being tied directly to the API |
| contracts of either of these environments). For commands that need to allocate |
| resources prior to delegation, and then release them upon return (even if a |
| delegated-to command throws an exception, the "filter" extension to "command" |
| provides a <code>postprocess()</code> method for this cleanup. Finally, |
| commands can be stored and looked up in a "catalog" to allow deferral of the |
| decision on which command (or chain) is actually executed.</p> |
| |
| <p>To maximize the usefulness of the Chain of Responsibility pattern APIs, |
| the fundamental interface contracts are defined in a manner with zero |
| dependencies other than an appropriate JDK. Convenience base class |
| implementations of these APIs are provided, as well as more specialized (but |
| optional) implementations for the web environment (i.e. servlets and portlets). |
| However, conditional compilation in the build script allows graceful creation |
| of the underlying API JAR file even in the absence of the optional dependencies. |
| </p> |
| |
| <p>Given that command implementations are designed to conform with these |
| recommendations, it should be feasible to utilize the Chain of Responsibility |
| APIs in the "front controller" of a web application framework (such as Struts), |
| but also be able to use it in the business logic and persistence tiers to |
| model complex computational requirements via composition. In addition, |
| separation of a computation into discrete commands that operate on a general |
| purpose context allows easier creation of commands that are unit testable, |
| because the impact of executing a command can be directly measured by observing |
| the corresponding state changes in the context that is supplied.</p> |
| |
| |
| <h3>(1) Scope of the Package</h3> |
| |
| <p>The fundamental API contracts of the Chain of Responsibility pattern are |
| encapsulated in the following interfaces in package |
| <code>org.apache.commons.chain</code>:</p> |
| <ul> |
| <li><strong>Command</strong> - An individual unit of work whose |
| <code>execute()</code> method is called to perform that work.</li> |
| <li><strong>Chain</strong> - A set of commands to which work will be |
| delegated, in a well-defined order, until one of the commands indicates |
| that work on a request has been completed. Note that a <code>Chain</code> |
| is itself a <code>Command</code>, so arbitrarily complex hierarchies of |
| execution may be composed.</li> |
| <li><strong>Filter</strong> - A specialized <code>Command</code> that requires |
| any <code>Chain</code> that executes it to promise a later call to the |
| <code>postprocess()</code> method if its <code>execute()</code> method |
| was ever called, even in the face of exceptions being thrown by subseuqently |
| called commands.</li> |
| <li><strong>Context</strong> - A container for attributes and properties that |
| represent the dynamic state of the computation being performed by a |
| <code>Command</code> or <code>Chain</code>. A <code>Context</code> |
| instance is passed to the <code>execute()</code> method of each |
| <code>Command</code>, which allows <code>Command</code> instances to be |
| easily shared in a multithread environment.</li> |
| <li><strong>Catalog</strong> - A collection of named <code>Command</code>s |
| (or <code>Chain</code>s) that can be used to symbolically identify a |
| computation to be performed.</li> |
| </ul> |
| |
| <p>In addition to the fundamental API contracts described above, additional |
| packages are provided (some of them optional based on the availability of |
| the corresponding APIs at compile time):</p> |
| <ul> |
| <li><strong>org.apache.commons.chain.impl</strong> - Convenience base class |
| implementations of the fundamental API contracts.</li> |
| <li><strong>org.apache.commons.chain.generic</strong> - Implementations of |
| <code>Command</code> that are completely generic across any execution |
| environment.</li> |
| <li><strong>org.apache.commons.chain.config</strong> - Implementation of |
| XML parsing rules (via the use of Commons Digester) so that a |
| <code>Catalog</code> instance can be populated with <code>Command</code> |
| and <code>Chain</code> instances configured from an XML document. |
| Optional, compiled only if commons-digester.jar is available.</li> |
| <li><strong>org.apache.commons.web</strong> - Abstract implementation |
| of <code>Context</code> that represents the fundamental characteristics |
| of request, session, and application scope objects in a web appication |
| environment, without being tied specificaly to the Servlet or Portlet |
| APIs. These characteristics are exposed under property names that are |
| identical to the "implicit variables" of the expression language that is |
| defined by JSTL 1.0 and JSP 2.0.</li> |
| <li><strong>org.apache.commons.web.faces</strong> - Concrete implementation |
| of <code>WebContext</code> for the JavaServer Faces API. Optional, |
| compiled only if the JavaServer Faces API classes are available.</li> |
| <li><strong>org.apache.commons.web.portlet</strong> - Concrete implementation |
| of <code>WebContext</code> for the Portlet API. Optional, compiled only |
| if the Portlet API classes are available.</li> |
| <li><strong>org.apache.commons.web.servlet</strong> - Concrete implementation |
| of <code>WebContext</code> for the Servlet API. Optional, compiled only |
| if the Servlet API classes are available.</li> |
| </ul> |
| |
| <p>Over time, it is expected that additional generic commands and specialized |
| contexts will be developed for specific requirements. However, conditional |
| compilation capabilities in the build script should be maintained so that a |
| user of commons-chain need only provide the APIs that he or she cares about. |
| Likewise, for maximum reuse, command implementations should be based on the |
| <code>org.apache.commons.chain.Context</code> API, rather than a more |
| specialized implementation class, if at all possible.</li> |
| |
| |
| <h3>(1.5) Interaction With Other Packages</h3> |
| |
| <p><em>Chain</em> relies on: |
| </p> |
| |
| <ul> |
| <li>Java Development Kit (Version 1.2 or later)</li> |
| <li>Commons BeanUtils (version 1.6 or later). OPTIONAL, required |
| only to use the <code>org.apache.commons.chain.config</code> |
| package.</li> |
| <li>Commons Collections (version 1.0 or later). OPTIONAL, required |
| only to use the <code>org.apache.commons.chain.config</code> |
| package.</li> |
| <li>Commons Digester (version 1.3 or later). OPTIONAL, required |
| only to use the <code>org.apache.commons.chain.config</code> |
| package.</li> |
| <li>Commons Logging (version 1.0.3 or later). OPTIONAL, required |
| only to use the <code>org.apache.commons.chain.config</code> |
| package.</li> |
| <li>JavaServer Faces API (version 1.0 or later). OPTIONAL, required only |
| to use the <code>org.apache.commons.web.faces</code> |
| package.</li> |
| <li>Portlet API (version 1.0 or later). OPTIONAL, required only |
| to use the <code>org.apache.commons.web.portlet</code> |
| package.</li> |
| <li>Servlet API (version 2.2 or later). OPTIONAL, required only |
| to use the <code>org.apache.commons.web.servlet</code> |
| package.</li> |
| </ul> |
| |
| |
| <h3>(2) Initial Source of the Package</h3> |
| |
| <p>This package represents a new approach to the Chain of Responsibility |
| pattern, and the initial source is provided by Craig R. McClanahan. It was |
| inspired by ideas from many sources -- in particular, the notion of a Chain |
| being a Command was copied from the way that handlers are described in Axis.</p> |
| |
| |
| <h3>(3) Required Jakarta-Commons Resources</h3> |
| |
| <ul> |
| |
| <li>CVS Repository - New directory <code>chain</code> in the |
| <code>jakarta-commons</code> CVS repository.</li> |
| |
| <li>Mailing List - Discussions will take place on the general |
| <em>commons-dev@jakarta.apache.org</em> mailing list. To help list |
| subscribers identify messages of interest, it is suggested that the |
| message subject of messages about this component be prefixed with |
| [Chain].</li> |
| |
| <li>Bugzilla - New component "Chain" under the "Commons" product |
| category, with appropriate version identifiers as needed.</li> |
| |
| |
| <h3>(4) Initial Committers</h3> |
| |
| <p>The initial committers on the Chain component shall be:</p> |
| |
| <ul> |
| <li>Craig R. McClanahan</li> |
| <li>TBD</li> |
| </ul> |
| |
| </body> |
| </html> |