Showing posts with label birt. Show all posts
Showing posts with label birt. Show all posts

Monday, 9 February 2009

Programming with Eclipse BIRT

A couple of years ago I started working on an Agent-Based Simulation System. This system simulated the behaviour of fleets of complex assets, such as aircraft, to support predictive analysis of maintenance, availability, system failure etc.

One of the (many) key challenges of the system architecture was the shear volume of data each simulation could potentially generate and the visualisation of the results. At the time the organisation I was working in hadn't decided on a corporate Business Intelligence / Analytics solution, so I had the task of looking for an appropriate technology to plug in to the system architecture.

It made sense that the solution was Open Source, looking around there were a few options including Jasper Reports, in the end I decided on Eclipse BIRT. I choose BIRT mainly because we were already using the Eclipse Platform for the rest of the system architecture development effort and, to be honest, I was quietly impressed with the capability, power and ease of use. Also BIRT has the advantage of being Open Source but with a solid commerical entity behind it in the form of Actuate.

BIRT's architecture is, essentially, split into two components, a Designer tool to maintain the report design, and a Java runtime Report Engine that manages and executes the report. The Designer component can either run as an Eclipse RCP client or Eclipse IDE Plug-In. The Report Engine will deploy to any standard Servlet Engine / J2ee Application Server environment, e.g. JBoss AS, Tomcat, Websphere etc.

An overview of the architecture is shown below.



The architecture of BIRT is pretty open and extensible. For example data source connectivity is provided by ODA which allows you to connect to different physical data sources, such as JDBC RDBMS, Web Services, Flat Files or Java Beans, yet treat them all as logic result sets. In fact, one of my first 'evaluations' of BIRT's capabilities involved building a web reporting front-end to Amazon's ECS (now known as AWS Associates Web Service).

For me, the real power of BIRT is the Server Event model that allows you alter the look, feel or behaviour of the report at runtime. An API is provided for the event model and can be accessed via Rhino (Javascript based scripting for Java) and native Java. An overview of the event model can be seen below.


Events are exposed on numerous report objects, for example DataSet.beforeOpen(), ReportElement.onPrepare() etc.

These events allow you to do all sort of 'clever stuff' at runtime. For example, change the SQL of a query based on a parameter or the outcome of a previous query, change repot or chart colours based on calculated values.

For example, the following code changes the SQL expression dependent on a runtime parameter rp_sortorder:

myDataSet.beforeOpen() {
this.queryText=this.queryText.replace('sortlistorder',params["rp_sortorder"]);
}

You can also get access the the J2EE runtime container. For example, the following code gets access to a Http Session object.

report.initialize() {
importPackage(Packages.javax.servlet.http);
var thisSession=reportContext.getHttpServletRequest().getSession();
var mySessionObject=thisSession.getAttribute("mySessionObject");
var mySessionObjectValue=mySessionObject.getValue();
}

As well as a Report Design and Runtime (Engine) API, there's a Chart API that allows to extend the built in Chart functionality. For example, the code below alters the scale of a chart dependent on two global variables "ymindate" and "ymaxdate".

function beforeGeneration(chart, icsc) {
importPackage(Packages.org.eclipse.birt.chart.model.data.impl);
var scriptObj=icsc.getExternalContext().getScriptable();
var yaxisminDate=scriptObj.getPersistentGlobalVariable("yminDate");
var yaxismaxDate=scriptObj.getPersistentGlobalVariable("ymaxDate");
var yaxismin=Date.parse(yaxisminDate);
var yaxismax=Date.parse(yaxismaxDate);
var xaxis=chart.getBaseAxes()[0];
var yaxis=chart.getOrthogonalAxes(xaxis,true)[0];
var yaxisScale=yaxis.getScale();
yaxisScale.setMin(DateTimeDataElementImpl.create(yaxismin));
yaxisScale.setMax(DateTimeDataElementImpl.create(yaxismax));
}

I am impressed with BIRT and I haven't yet found a reporting / analytics requirement it can't handle, coupled with it's extensibility and the backing of the Eclipse community and Actuate I highly recommend it.

If you want to find out more about BIRT: