The Cocoon Processing Model
There are two ways of describing the Cocoon architectureone simple, the other complicated. The simple description is that Cocoon is a servlet. Easy enough, but this is such an over-simplification that it becomes an untruth! To truly describe the architecture of Cocoon requires that we look at various aspects of how Cocoon is put together.
Although Cocoon is typically thought of as a servlet, this is really an incorrect stance. The typical way Cocoon is accessed is via a servlet, but strictly speaking, that is simply providing an access interface to a powerful publishing mechanism. Cocoon was designed to be interfaced to in a flexible way. As an example, Cocoon also provides a command-line interface; in fact, this is the method that is used to generate the documentation via the Ant build process.
Cocoon is similar to most modern-day applications in that it is made up of layers of processing technology. Avalon forms part of the core infrastructure on which Cocoon sits; however, Cocoon is much more than an implementation of Avalon components. It should come as no surprise to discover that Cocoon is made up of layers of technology (see Figure 3.1) that gradually focus in on the ultimate purpose: running your code in your application.
Figure 3.1 Cocoon Component Architecture.
Cocoon's base layer provides the wrapper around Avalon, contextualizing the infrastructure for the bespoke requirements of Cocoon.
At the heart of Cocoon is Avalon. As discussed in the preceding chapter, Cocoon makes use of the infrastructure and core components that Avalon provides. This foundation provides the staple logic for the rest of Cocoon such as logging, database connection pooling, configuration management, thread handling, and object pooling.
Just above the Avalon components is the Cocoon caching mechanism. Cocoon takes care of caching the responses to requests, thus speeding up multiple accesses to the same page. The mechanism is based on the Avalon caching components but is extended to meet the specific needs of Cocoon. In addition, Cocoon can pool components to support better performance. Again, this is a specific implementation of the interfaces that Avalon supplies.
The pipeline is a key aspect of Cocoon. If you consider a Web server processing a request for an HTML page, the server will get the request, find the file, and serve the response back. This can be made more complex if, for example, the response is dynamically formed using something like PHP. In this case, the request is passed to another block of code that handles the generation of the PHP.
Cocoon is more complex than this, requiring the generation and transformation of XML streams. The number of steps between request and response can be many; therefore, the pipeline is designed to act as a "marshall," defining the steps and controlling the entry and exit from one to anotherbasically coordinating the steps. The pipeline is controlled through a configuration file known as the sitemap. We will cover the sitemap in more detail in the next chapter.
Program Generation and Base Component Classes
As the pipeline is processed, base components are used to handle, generate, compile, load, and execute logic. Components exist to manage the generation of XML data streams, transform these streams, and serialize the result into whatever format is required. The base components extend Avalon components and form the key classes and interfaces for specific components to be built on. The base component classes also include component management functions that support the administration of component selection and lifecycle. This is done using the principles of Inversion of Control and Separation of Concerns, thus following the patterns promoted by Avalon.