Automated Coder

23 September, 2008

Building with NVelocity

Filed under: CruiseControl.Net — Tags: — Craig Sutherland @ 10:59 pm

Finishing the Dashboard

In my previous articles I’ve covered a lot of the “core” functionality of the web dashboard – how it works and its pieces. As the end goal of the dashboard is to render HTML content, I’ve covered the various classes that contribute towards this goal – responses, templates and actions. But so far I haven’t covered the actual HTML generator itself – IVelocityViewGenerator. This post will look into the workings of this interface, both the classes that implement it and the process for actually generating the full HTML page that is sent to the client.

Wrapping the Generator

The actual HTML generator is the NVelocity engine – but this functionality is encapsulated in a series of classes and interfaces. Every action that generates HTML uses the IVelocityViewGenerator interface. This interface has a single method – GenerateView(). This method takes in a template name and a hashtable of context items and generates an HtmlFragmentResponse containing the HTML. The actual template only contains a fraction of the page – the generator is responsible for adding everything else.

The only implementation of IVelocityViewGenerator is VelocityViewGeneratorWithTransformer. This class is merely a wrapper around IVelocityTransformer, which is implemented by LazilyInitialisingVelocityTransformer. This class contains the reference to a VelocityEngine - the heart of the NVelocity library. As it’s name implies, it only loads the engine when required, and when it does it loads all the required settings (the location of the templates, logging and resource manager classes).

And that’s all the view generator actually does – it just hides the view engine. So, how is the actual page generated?

Back to Objection

Remember all the way back to my first post on the web dashboard? I talked about types like ObjectStore and CruiseObjectSourceInitializer - these actually do a bit more work behind the scenes. As part of the initialisation of an object in the store they do something called decorating them. These “decorations” are actually wrapper classes that contain the actual actions, and do various pieces of work around the actions. It can be thought of as building a chain of operations to perform for an action.

The following shows the chain of operations for a farm action (this is typical for any generic action):

Farm Chain of Operations
Farm Chain of Operations

In the case of building the page HTML, there is a “decoration” called SiteTemplateActionDecorator. Like all actions, this implements the IAction interface, plus it contains a references to the wrapped action. When the RequestController instantiates an instance of an action, it actually gets a chain of actions including the SiteTemplateActionDecorator (assuming it is performing an action that generates HTML).

Building a Full Page

When the Execute() method on SiteTemplateActionDecorator is called it does a number of things:

  1. Call Execute() on the wrapped action
  2. Generates HTML fragments for the breadcrumbs, side bar, header and footers and stores them in an hashtable
  3. Calls IVelocityViewGenerator on a site template to generate the final page

The breadcrumbs, side bar, header and footers are all small templates that contain just the required details. There are “builder” classes around these templates that decide which template should be rendered (e.g. farm, server, project or build), plus builds the hashtables with the context details. Most of these builders are simple – they just see what items are in the ICruiseRequest instance and then set the template and context items. They are a bit more involved than just an action as they need to handle all cases (e.g. the different levels within the dashboard).

And That’s All!

That pretty much wraps up this series of post on the web dashboard and how it works. While the dashboard is fairly complex, this complexity allows for a wide range of extensible functionality. This ability to extend the dashboard made it harder to figure out how it worked, but time, persistence and liberal use of the debugger in VS2008 helped to crack it open :)

If all that is needed is a new plug-in, just implement IPlugin and IAction (I’ll write up something on doing this at some point). If more is needed, then hopefully these posts will help. Now I know I haven’t covered every single detail of the dashboard, but it is enough to give me an understanding of how it works for my next project – adding security to the dashboard!

Stay tuned…

No Comments Yet »

No comments yet.

RSS feed for comments on this post. TrackBack URI

Leave a comment

Blog at WordPress.com.