The reportContext object
Almost every event handler has access to an object called the reportContext object. Table 37-1 lists commonly used reportContext object methods.
Table 37-1 Methods of the reportContext class
Method
Task
deleteGlobalVariable( )
Deletes a global variable created using setGlobalVariable( ).
deletePersistentGlobalVariable( )
Deletes a persistent global variable created using setPersistentGlobalVariable( ).
evaluate( )
Evaluates a JavaScript expression.
getAppContext( )
Returns the application context that stores many variables that the engine uses to process the reports.
getDesignHandle( )
Retrieves the design handle for the currently running report. Use the design handle to manipulate the report design before processing starts. For example, to add, modify or drop report items programmatically. Modify a design in the beforeFactory event.
getGlobalVariable( )
Returns a global variable created using setGlobalVariable( ). This type of global variable is not stored in a report document.
getHttpServletRequest( )
Returns the HTTP servlet request object.
getLocale( )
Returns the current java.util.Locale object.
getMessage( )
Returns a localized message from the localization resource file.
getOutputFormat( )
Returns the format of the emitted report.
getPageVariable( )
Gets a page variable. Do not use this method in report‑level events such as the beforeFactory as the page variables have not yet initialized.
getParameterDisplayText( )
Returns the display text of the parameter name passed to the method.
getParameterValue( )
Returns a parameter value.
getPersistentGlobalVariable( )
Returns a persistent global variable created using setPersistentGlobalVariable( ). This type of global variable is stored in the report document.
getReportRunnable( )
Returns the runnable report design handle to retrieve report properties and engine configuration information.
getResource( )
Returns the URL to the resource passed to the method, such as the URL of an image stored in the resource folder.
getTimeZone( )
Retrieves the com.ibm.icu.util.TimeZone instance for the currently running report.
setGlobalVariable( )
Creates a global variable accessible using getGlobalVariable( ).
setPageVariable( )
Sets a page variable. Do not use this method in report‑level events such as the beforeFactory as the page variables have not yet initialized.
setParameterValue( )
Sets the value of a named parameter.
setPersistentGlobalVariable( )
Creates a persistent global variable accessible using getPersistentGlobalVariable( ).
Using getOutputFormat
The output format for a report is available in the rendering phase of report generation. Call the getOutputFormat( ) method of the reportContext object to determine the output format in the beforeRender, onRender, or afterRender event handlers. For example, to change styling for an element depending on the output format, add code to the onRender event handler, as shown in Listing 37‑3.
Listing 37‑3 onRender event script
if ( reportContext.getOutputFormat( ) == "pdf" ){
this.getStyle( ).backgroundColor = "red";
}else{
this.getStyle( ).backgroundColor = "blue";
}
Accessing the report design handle
You can use the reportContext object to retrieve the report design handle in the beforeFactory event handler. You can modify the currently running design before the design executes.
Place the following event handler examples in the beforeFactory method, which executes only during the generation phase of report creation. The examples use the Design Engine API, which is described in a later chapter.
The example in Listing 37‑4 uses the design handle to add a filter based on report parameters to a table.
Listing 37‑4 Using a parameter to filter a table
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.report.model.api
.elements);
tableHandle = reportContext.getDesignHandle( )
.findElement("mytable");
if( params["FilterCol"].value.length > 0 ){
fc = StructureFactory.createFilterCond( );
fc.setExpr( "row['" + params["FilterCol"] + "']" );
fc.setOperator( params["FilterEq"] );
fc.setValue1( "\"" + unescape(params["FilterVal"]) + "\"" );
ph = tableHandle.getPropertyHandle( TableHandle.FILTER_PROP );
ph.addItem( fc );
}
The example in Listing 37‑5 is similar to the filter example. It adds a sort condition to a table.
Listing 37‑5 Sorting a table
importPackage(Packages.org.eclipse.birt.report.model.api);
importPackage(Packages.org.eclipse.birt.report.model.api
.elements);
tbl = reportContext.getDesignHandle( ).findElement("mytable");
sc = StructureFactory.createSortKey( );
sc.setKey("row[\"PRODUCTCODE\"]");
sc.setDirection("desc");
ph = tbl.getPropertyHandle(TableHandle.SORT_PROP);
ph.addItem(sc);
A report developer may hide a portion of report content using the visibility property. Hidden content can customize the display of data based on report parameters or perform an unrendered calculation. A report item hidden by its visibility property is still processed, which may or may not be desirable.
As an alternative to using the visibility property, use the report design handle to drop elements from a running design, as shown in the following code:
reportContext.getDesignHandle( ).findElement( "table1" ).drop( );
You can alter additional properties of report items. Listing 37‑6 shows how to resize the width of a column within a table and change the bound data set. If the bound data set for a report item changes, the new data set must contain the same columns as the previous data set.
Listing 37‑6 Changing table properties
th = reportContext.getDesignHandle( ).findElement( "table1" );
ch = table.getColumns( ).get(0);
ch.setProperty( "width", "10%" );
th.setProperty( "dataSet", "My Alternate Data Set" );
You can change the styles property in the beforeFactory event. Listing 37‑7 uses one style for PDF generation and another style for all others. This example requires the report document be recreated to effect the change. Alternatively, use the RunAndRender task.
Listing 37‑7 Changing a table style
th = reportContext.getDesignHandle( ).findElement( "mytable" );
rh = tableHandle.getDetail( ).get(0);
if( reportContext.getOutputFormat( ) == "pdf" ){
rh.setStyleName( "style2" );
}else{ rh.setStyleName( "style1" ); }
Passing a value between processes
A global JavaScript variable cannot pass a value between processes, but scripts often need to pass a value from the factory process to the render process. The BIRT report context object uses persistent global variables to pass values between the processes. These variables must be serializable Java objects. The setPersistentGlobalVariable( ) method creates a variable that is accessible using the getPersistentGlobalVariable( ) method.
For example, generate two strings at run time and display one string when rendering in PDF and a different string in other format contexts. Use the setPersistentGlobalVariable( ) method at generation time to store the variables in the report document. At render time, retrieve the variables in a render event handler using the getPersistentGlobalVariable( ) method.
Listing 37‑8 calls the setPeristentGlobalVariable( ) method in the onCreate event handler of a label element to initialize two strings then calls the getPersistentGlobalVariable( ) method in the onRender event handler to specify the format context.
Listing 37‑8 Using persistent global variables
//Label onCreate
reportContext.setPersistentGlobalVariable( "mypdfstr",
"My PDF String" );
reportContext.setPersistentGlobalVariable( "myhtmlstr",
"My HTML String" );
//Label onRender
if( reportContext.getOutputFormat( ) == "pdf" ){
this.text = reportContext.getPersistentGlobalVariable( "mypdfstr" );
}else{
this.text = reportContext.getPersistentGlobalVariable( "myhtmlstr" );
}
Using getAppContext
BIRT uses an application context map to store values and objects for use in all phases of report generation and presentation. To add an object to the application context, use the Report Engine API or the setAttribute( ) method of the request object.
The JSP example shown in Listing 37‑9 adds an object to the application context. AppContextKey is the name that references the object and AppContextValue contains the value of the object.
Listing 37‑9 Adding an object to the application context
<%
java.lang.String teststr = "MyTest";
session.setAttribute( "AppContextKey", teststr );
java.lang.String stringObj =
"This test my Application Context From the Viewer";
session.setAttribute( "AppContextValue", stringObj );
String redirectURL = "http://localhost:8080/4.3.1/frameset
?__report=AppContext.rptdesign";
response.sendRedirect( redirectURL );
%>
Reference an object in the application context. Listing 37‑10 uses a try‑catch block to detect whether the object is not found and returns an appropriate error message.
Listing 37‑10 Checking for the presence of an object
try {
MyTest.toString( );
} catch (e) {
"My Object Was Not Found";
}
Use the EngineConfig class or the EngineTask class in the Report Engine API to add an object, as shown in Listing 37‑11.
Listing 37‑11 Adding an object to the application context
config = new EngineConfig( );
HashMap hm = config.getAppContext( );
hm.put( "MyTest", stringObj);
config.setAppContext(hm);
The application context object contains many useful settings. For example, set the driver location for JDBC drivers using code similar to the following lines:
config.getAppContext( ).put("OdaJDBCDriverClassPath",
"C:/apps/apache-tomcat-5.5.20/webapps/4.3.1/WEB-INF/lib");
Setting a location for JDBC drivers precludes putting the driver JAR file in the JDBC plug‑in, eliminating the possible deployment of multiple copies of a JDBC driver to the application server. Additionally, the connection object can be passed in to the BIRT engine using the OdaJDBCDriverPassInConnection setting of the application context. The value of the object must be an instance of a java.sql.Connection object. By passing in a connection, you can control whether the engine closes the external connection object by using the OdaJDBCDriverPassInConnectionCloseAfterUse setting. The value for this setting is a Boolean value.
Setting application context objects from script is also possible. Properties must be set before use. Many settings apply to all tasks that the engine spawns. Changed settings affect all subsequent report runs.
Use the reportContext.getAppContext method to iterate through all the objects in the application context, as shown in Listing 37‑12.
Listing 37‑12 Examining all objects in the application context
iter = reportContext.getAppContext( ).entrySet( ).iterator( );
siz = reportContext.getAppContext( ).size( );
kys = "";
vls = "";
while (iter.hasNext( )){
innerObject = iter.next( );
kys = kys + innerObject.getKey( ) + "\n";
val = innerObject.getValue( );
if( val != null ){
vls = vls + innerObject.getValue( ).toString( ) + "\n";
}else{
vls = vls + "NULL" + "\n";
}
}
This code makes the variables, kys and vls, available for display in a data element or text element. Use kys and vls in an expression for a data element or <VALUE‑OF>kys</VALUE-OF> and <VALUE-OF>vls</VALUE-OF> in a text element.
Getting information from an HTTP request object
The HTTP servlet request object contains methods to retrieve information about the request to run the report. One useful method of the HTTP request object gets the query string that follows the path in the request URL. The query string contains all the parameters for the request. By parsing the query string, the code can extract the parameters in the request URL conditionally to determine the report output. For example, use this feature to pass in a user ID or to set or override a report parameter. Listing 37‑13 gets the query string.
Listing 37‑13 Getting the query string from a request URL
importPackage( Packages.javax.servlet.http );
httpServletReq = reportContext.getHttpServletRequest( );
formatStr=httpServletReq.getQueryString( );
You can retrieve a Session object using reportContext, as shown in the following code:
var request = reportContext.getHttpServletRequest( );
var session = request.getSession( );
session.setAttribute("ReportAttribute", myAttribute);