Friday, April 07, 2006

BIRT and the eval command

While JavaScript’s eval function has been around for quite some time, I thought it might be a good idea to show an example of it working with BIRT. BIRT uses the Rhino engine for server side scripting and has an event model that allows writing handlers in JavaScript or Java. These handlers will be executed at key locations during the report generation and rendering processes. When implementing these in JavaScript the developer has access to the JavaScript native functions. The scripts that are implemented are stored within the XML report design. In addition to the event handlers, the BIRT Expression Builder uses JavaScript. The Expression Builder is used to assign values or modify attributes for a report element.. For example, evaluating the URL for a hyperlink or setting the value of a Data element is accomplished using the Expression Builder. The key to the expression builder is that it always returns a value. This is generally just a data value like row[“CustomerNumber”], but it also supports conditional logic and access to native JavaScript functions.

This gets me to the eval function. What if I want the script that executes in the expression builder to be dynamic? This may be useful when the calling application desires a certain Java class, not know at runtime, be loaded or the script that is used needs to be customized at runtime. This can be achieved in BIRT by adding a string parameter to the report that contains the script and using eval on the Expression Builder where the script is needed.

To illustrate I have created the following simple Java class. I will be using the getter methods for each of the three test cases. The first returns an int, the second a String and the third a HashMap. Make sure that this class is in WEB-INF/lib directory for the viewer plugin.

package my.simple.code;
import java.util.HashMap;

public class EvalTest {
private int testOne;
private String testTwo;
private HashMap testThree;
public int getTestOne() {
return testOne;
public String getTestTwo() {
return testTwo;
public HashMap getTestThree() {
return testThree;
public EvalTest() {
testTwo="My Test String";
testThree = new HashMap();
testThree.put("hm0", "Test String Map 0");
testThree.put("hm1", "Test String Map 1");
testThree.put("hm2", "Test String Map 2");



Now create a report with the following elements.

Element - Value
Label – “Command to be Executed”
Data - params["JavaScriptEvalCommand"]
Label – Results of Command
Data - eval(params["JavaScriptEvalCommand"]);

Next add a String Parameter named JavaScriptEvalCommand and set its default value to
x =new; y=x.getTestThree(); y.get("hm2");

Run the report. The output will be as follows:

Command To Be Executed
x =new; y=x.getTestThree(); y.get("hm2");
Results of the Command
Test String Map 2

Now change the parameter to call test one and two, and the results should reflect what is in the Java class.
Parameter Value or test one and two:
x =new; y=x.getTestTwo();
x =new; y=x.getTestOne();

Using eval is powerful, but it does come with some drawbacks. First and foremost is that report debugging becomes more complex. Using a Java Event Handler is probably a better solution in most cases. Another issue when using the eval function within the Expression Builder is that you can only return one value. Finally parameter validation can be very difficult.


Anonymous said...

Hi, am using birt 2.0.1 version in my apllication ,but facing some issues like some data missing for eg: in column "client Name" it is displaying "ame" if i run report 2nd times it wont repeat,may this problem is because of version and we using data source as i want to update version like 2.1 series ,can u plz list me what are jar files and plugin's i need to update and is it effect sourcecode ....

advance thanks

shaker Reddy said...

Please help , how to set (pageBreakIntervel) in birt3.0

thanks in advance

shaker Reddy said...

HI , can any one help, how to use setPageIntervel in birt3.0

thanks in advance

Jason Weathersby said...

Take a look at this example: