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