tags:

views:

109

answers:

1

I'm building a report that needs to include an 'estimate' column, which is based on data that's not available in the dataset.

Ideally I'd like to be able to define a Java interface

public int getEstimate(int foo_id, int bar_id, int quantity);

where foo_id, bar_id and quantity are available in the row I want the estimate presented.

There will be multiple strategies for producing the estimate so it would be good to use an interface to allow swapping them when needed.

Looking at the BIRT docs, I think it's possible I ought to be using the event handler mechanisms, but that seems to only allow defining a class to use and I'd somehow like to inject a configured estimator.

A non-obfuscated example might be to say that I have a dataset which includes an IP address column, and I'd like to be able to use some GeoIP service to resolve the country from the IP address. In that case I'd have an interface public String getCountryName(String address) and the actual implementations may use MaxMind, a local cache or some other system.

How would I go about doing this?

Or.. would I be better off by writing a scripted data source that can integrate the computed data before delivering it to BIRT?

Or.. some sort of scripted data source that is then used to create a join data set?

A: 

I think a Scripted Data Source would work fine, but a Java-based event handler would be more straightforward. You can implement it as a simple POJO and get access to any and all the complex objects and tools that will allow you to calculate your estimate. The simplest solution of all may simply to be adding a calculated field to the data set.

When creating the calculated field, you can get pretty complex in terms of the scripting logic you can leverage in order to produce the resultant value. The nicest thing about this route is that all the other column values in the row (which I assume you need to calculate the estimate) are made available via the Expression editor. You can pull in complex objects (POJOs) to help in your calculations here as well by using the "Packages" object (i.e. var red = new Packages.redwood.HelloWorld())

If you want to create the Event Handler class, here is what I would do. I would create a text object and bind the onCreate even to your POJO (by extending the TextItemEventAdapter) and override the "onCreate" method. There you can do any work you want to and at the end simply call 'text.setText(theEstimateResult);' to make the estimate itself visible. As far as accessing data values to do your calculations, You can get to those in the POJO too. I assume the estimate will be a part of a larger table of values. You can access any specific row value via the reportContext.

Those are the two ideas I would give a try first. The computed column is the fastest to implement and the least likely to throw you a curve during deployment. Let me know which way you choose and we can hash it out further if needed.

MystikSpiral
I'm trying to see how, in your example, the redwood.HelloWord instance would be able to have pre-configured properties not from the BIRT script. For example, my Spring context, within which I'm trying to run BIRT, may have a service interface implementation that my estimator needs to use. Instantiating HelloWorld directly means it then needs configuring. Maybe I need to look at Spring AOP to inject dynamically, but I suspect the BIRT OSGI bit might get in the way.The event handlers look nice but I just don't know how to get a reference to an pre-existing, external-to-birt, instance.
ptomli
In the event handler example, if you need to grab a pre-existing instance of something (and you are running within the same VM) then you likely need that "something" to implement the Singleton pattern. A private constructor and a public "getInstance()" method. This will allow you to grab it from the POJO pretty easily.
MystikSpiral
OK, I'm going to try a couple of variants and see what falls out. I think a datasource would provide better mechanisms of control within Spring (I can inject an instance, avoiding Singleton) though the event handler has a good 'feel' to it (specific classes for specific purposes). Thanks
ptomli