tiles-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Nicolas LE BAS <m...@nlebas.net>
Subject Implementing Tiles Request (1/3): the context hierarchy
Date Wed, 29 Aug 2012 18:00:39 GMT
I'd like to discuss here a few decisions that you have to make when
implementing Tiles Request. Mick and I have been doing that for some
time now, and a few patterns have emerged. Some are clearly better than
others, in some other situations it is much less clear.

In Gamma's terminology, the Request interface is a Facade: it "provides
a unified interface to a set of interfaces in a subsystem", and "defines
a higher-level interface that makes the subsystem easier to use".
Request regroups several concerns into a single interface, the most
significant are:
- attributes regrouped by "context". We usually assume these "contexts"
are hierachical and related to the lifespan of the objects they contain,
after the fashion of the Servlet API, but very little is explicitely
defined by the Request API.
- a Writer serving as output for the renderer.

When implementing Tiles Request, we're usually writing some kind of
adapter in order to make these two concepts fit with an alien API.

* The context hierarchy.

Very little is explicitely defined by the API about the contexts, with
only one explicit constraint, List<String>: the contexts are ordered.
Since TREQ 1.0.2, I've documented it as short to long lifespan, with
"request" and "application" as mandatory, because the existing
implementations adhere to that. But actually, there's more to discuss.

Tiles DefaultLocaleResolver relies on a "session" scope, and I'm
reluctant to make that one mandatory at API level. Even in a Servlet
environment, sometimes you don't need the whole session handling
mechanism, and you may even want to avoid it in M2M situations (like
atom feeds for instance).

Then there's the question of what each context exactly means.

"application" is assumed to be the same as
getApplicationContext().getApplicationScope(), that's clear enough.

What is "request"? Based on the Serlvet API, I would define "request" as
a scope that is accessible for reading and writing at every stage of the
rendering process; it stays accessible through all eventual wrappers and
adapters, including RequestWrappers and alien adapters such as
freemarker's Environment or velocity's Context or HttpServletRequest.
And it is the first scope to do so (ordered as in getAvailableScopes):
an eventual "page" scope would be discarded when the process flow passes
from one page to another (i.e. a Renderer has finished processing the
request).

And then the other contexts would be optional and treated according to
their position relative to "request". Do we need to normalize their
names, like "session" or "page"?

Servlet/JSP follow this behaviour when including content, while
Freemarker is a little more complex (although it supports JSP-compatible
behaviour) and Velocity has no "page" scope, just nothing below the
"request" scope. Mustache makes it easy by not writing to the request at
all.

What do you think? Does this analysis seem correct to you? Did I miss
some part of it?

Then there is this: currently RequestWrapper for instance is just
delegating all calls to the wrapped request. Should we enforce the
wrapping policy for the various scopes in an abstract class, for instance?

TBC...

Mime
View raw message