Motivation and design goals

Do not introduce features which make standard tasks more complicated
just because they would make a non-standard task easier.

Stay indepented of the view component. Of course it is very easy
to use Facade with SiTE but
you can also use JSP.

There
seems to be a common understanding how the controller and overall architecture
of the MVC framework should be done, but there are a couple of totally
incompatible implementations for the view part (Velocity, XMLC, JSP,
SiTE, WebMacro, ....). A design goal of Facade is to overcome this and provide an
interface which enables you to hook your favorite view implementation into
Facade. Of course there are lot of benefits if you use SiTE and the
SiTE viewhandlers.

Architecture overview

The processing of each request is divided into two phases:

Request processing: performing actions on the model and selecting
the response view.

Response composing: filling the view(s) and delivering a response back to
the client.

The most important objects in the Facade
architecture are the
EventDispatcher, EventHandler and the
FacadeContext classes. There are two event dispatches by default,
a ControlEventDispatcher and a ViewEventDispatcher. As one might guess
the ControlEventDispatcher is responsible for phase one and dispatches events to controllers. The
ViewEventDispatcher is responsible for phase two and dispatches events to view handlers. Controllers
and view handlers implement the EventHandler interface. The FacadeContext
is used to share information among event handlers.

Request processing

Any incoming request is mapped to an event URL. The FacadeServlet
composes the event URL using the request URI and dispatches the event URL
using the ControlEventDispatcher. The ControlEventDispatcher
calls the appropriate controller(s).

A controller can listen to one or more event URLs. Each request is handled by zero or more controllers.
Any controller can require other controllers. E. g. if controller
A requires controllers B and C, B and C are executed before A.

Each controller may perform operations on the model or e. g. check
the format of request parameters. If a controller finishes successfully
without throwing an exception or dispatching an event the request is passed on to the next
controller.

Some event URLs may have no registered listeners (eventhandlers), so the application
tries to guess the eventhandler class name based on the event URL. Let's say
the request URL is somthing like http://mysuperbiz.com/webapp/facade/affiliate/Login/. The
computed event URL will be "affiliate/Login". Facade will then try to
invoke the class your.default.event.handler.package.affiliate.LoginController.

Every eventhandler has access to the ControlEventDispatcher and the ViewEventDispatcher and
may dispatch events. If you dispatch (fire) an event, identified by it's event URL, it will
be handled immediately. All listening eventhandlers and default eventhandlers will be called at
once. You do not have to care about event queues.

Any controller may dispatch a view event. If no controller
dispatches a view event, the FacadeServlet itself will dispatch a view event with
an event URL computed form the request URL.

Response composing

The response is composed and sent back to the client by one or
several viewhandlers. A viewhandler can listen to one or more event URLs.
A viewhandler may define a fallback handler. The fallback handler is called
if the viewhandler cannot compose a response and throws an exception. The
top level fallback handler is Facade's internal GeneralErrorEventHandler,
which composes a very basic error page and sends it back to the client.

Facade tries to send a response to the client until the
FacadeContext.isResponseSend() method returns true. Naturally this means your
ViewHandler will have to call FacadeContext.setResponseSend(true) if a
response was sent. If no appropriate viewhandler is found Facade sends
an error page.

A viewhandler concept which enbles you to use page components
and uses the features of Facade is the SiTEViewHandler. A page component is a
server side filled presentation code snippet which can be included or imported
on multiple pages.

SiTEViewHandler for Facade

The idea

Since we recently created
SiTE, a useful
template engine, it seemed reasonable to create a ViewHandler for the Facade
framework based on SiTE templates.

While it makes sense to have some generic template processing based on a given
Facade context, it also makes sense to extend the idea of handlers to the
SiTE framework. Generally speaking, any node in a SiTE template can define an
event to be fired when it's being processed. Facade event handlers can listen to
these events and process the node. Any node which does not fire a specific
event will be processed by the default handler(s).

This is possible without changing the SiTE API by simply using a special
attribute for defining the event url. The name of the attribute is
configurable and defaults to "FACADEEVENT".

Default handlers

There are two default handlers to start with. The second is an extension of
the first. Given a facade context, SiteViewHandler handles a given node
like this:

If the node has a "FACADEEVENT" attribute that contains an event url, the
event will be fired. A reference to the node will be stored in the
facade context under the key "sitenode".

If the node is of type "form", an instance of SiTEViewFormHandler is created
and used to handle the node.

If for the name of the node there is a String value in the given context,
all children of the node are replaced by the value.

If there is a boolean value that equals false for the name of the node in
the given context, the node is removed.

SiTEViewFormHandler applies the same steps where an additional step is inserted
before step 3 in the list above:

If the node is an input node (type "input", "select", "textarea") and for
the attribute "name" of the node there is a String value in the given
context, the "value" of the node is set appropriately. Note that setting
the value involves different operations for different types of input node.