Abstracting requests and templates
If you are following the developments of the Tiles sandbox you might have noticed that there are three projects:
- the usual Tiles project, the version 3;
- the "tiles-request" project, a project to abstract the concept of "request"
- the "tiles-autotag", a project that I would like to auto-generate tags (or tag-like) artifact from a common template code.
Tiles Request microframework
We've all seen that the various technologies like Servlet, Portlet, JSP, Velocity, FreeMarker seem to have a different abstraction of a common pattern. They all have a concept of:
- request: the client request, or some sort of it;
- response: the response to send to the client, or to the caller, with a writer/output stream to write into;
- attributes: usually maps (or map-like structures) with string keys and object values;
- scope: places where different attribute maps are stored (request, session, etc.)
Now all of these scopes are concentrated into the "Request" interfaces, that acts as a single point of reference for the developer. In theory, everything can be obtained by an object that implements Request.
Currently there are bindings for Servlet, Portlet, JSP, Velocity and FreeMarker.
The Tiles Request microframework is 100% developed.
Autotag: generate tags from a common template
When I wished to add FreeMarker support, in Tiles 2.2, I've seen a pattern: most of the code was perfectly the same. So I created the "Tiles template" module that contains all of this common code that will be called by JSP taglibs, FreeMarker directives and Velocity directives.
There was a problem though: the request layer of Tiles 2.2 does not contain all of the needed concept of a complete abstraction. If you see ImportAttributeModel in particular, there is an exception to the pattern: the "getImportedAttributes" returns something, the other template classes are void.
Thanks to the Tiles Request microframework, in Tiles 3 these template are perfectly the same:
- body tags have a "start" and "end" methods with a variable number of parameters, the last one is a Request, and the body is in the "end" method, if needed;
- body-less tags have an "execute" method, like the "start" method above.
The JSP tags and directives in Velocity and FreeMarker support are simply boilerplate code, that might be generated automatically in some way.
This code generation should be done in two steps:
- source code analisys of the template code, that extracts an object model of these classes, including Javadocs;
- code generation, that takes the model above and generates boilerplate code for the various platforms.
I almost accomplished the first task thanks to QDox, a source code analisys tool that extracts Javadocs too (cool! cooler than Compiler Tree API that I failed to use since it was too difficult). Check out the tiles-autotag-core project yourself: there is a JUnit test that builds a model from some sample classes.
There are still problems, in particular:
- how to identify mandatory parameters?
- how to identify the "body" parameter?
The second step will use a template to parse the model above. I hope to use Velocity for this.
Everything will be wrapped into a Maven plugin with two goals:
- one to deduce the model and publish it as an artifact containing an XML;
- one to read the model and generate technology-specific (for JSP, Velocity etc.) code.