Chapter 10. Using Java to Write an Event Handler

Creating a Java event handler is slightly more complex than creating a JavaScript event handler because you cannot simply enter Java code directly in the BIRT report designer. To create a Java event handler class, you must compile the source for the Java class and make certain that the class is visible to BIRT. Creating a Java event handler for BIRT is simplified, however, by the fact that Eclipse is a robust Java development environment and supports integrating a Java project with a BIRT project.

This chapter discusses the following topics:

  • Writing the event handler class

  • Making the event handler class visible to BIRT

  • Associating the event handler class with a report item

  • Understanding the classes and interfaces associated with Java event handlers

Writing a Java event handler class

When you provide one or more Java event handlers for a scriptable BIRT element, you must create one class that contains all the Java event handlers for that element. Creating a class that contains event handler methods for more than one element is not advisable.

BIRT provides a set of Java interfaces and Java adapter classes to simplify the process of writing a Java event handler class. There is one interface and one adapter class for every scriptable BIRT element. An element’s event handler interface defines all the event handler methods for that element. A handler class must implement every method defined in the interface, even if some of the methods are empty.

Locating the JAR files that an event handler requires

There are two JAR files that contain all the classes and interfaces that an event handler requires. One of the JAR files is a part of BIRT Report Designer and SDK and the other one is a part of BIRT Report Engine.

The JAR file that you use for developing a Java event handler is org.eclipse.birt.report.engine_Version.jar, which is located in the Eclipse plugins directory for BIRT Report Designer and SDK.

The JAR file that you use when you deploy your report is scriptapi.jar, which is located in the WebViewerExampleWEB-INFlib directory of BIRT Report Engine. All JAR files in the WebViewerExampleWEB-INFlib directory are in a deployed report’s classpath, so there is no need to do anything special to make scriptapi.jar accessible at run time.

Extending an adapter class

An element’s adapter class implements the element’s interface and provides empty stubs for every method. To use the adapter class, extend the adapter class and override the methods for which you are providing handler code. Eclipse recommends extending an adapter class rather than implementing an interface directly.

BIRT naming conventions for the event handler interfaces and adapter classes are discussed later in this chapter.

How to create an event handler class and add it to the Java project

This section describes the process for using the Eclipse Java development environment to create an event handler class for a scriptable BIRT element.

  1. Add org.eclipse.birt.report.engine_Version.jar to your Java project, as outlined in the following steps:

    1. Select your Java project and choose File→Properties→Java Build Path→Libraries. Java Build Path appears, as shown in Figure 10-1.

      Adding a JAR file to the compiler’s classpath

      Figure 10-1. Adding a JAR file to the compiler’s classpath

    2. Choose Add External JARs. JAR Selection appears.

    3. Navigate to Eclipse /plugins directory. In a default Eclipse installation, this directory is in the following location:

      C:eclipseplugins
    4. Select org.eclipse.birt.report.engine_Version.jar. Choose Add. Java Build Path appears.

    5. Choose OK.

  2. Select your Java project and choose File→New→Other. Select a wizard appears.

  3. Expand Java and select Class, as shown in Figure 10-2.

    The Select a wizard dialog

    Figure 10-2. The Select a wizard dialog

    Choose Next. Java Class appears, as shown in Figure 10-3.

    Java Class

    Figure 10-3. Java Class

  4. Navigate to the folder where you want the Java source file to reside by choosing the Browse button beside Source Folder.

  5. If your new Java class is a part of a package, type the fully qualified package name in Package.

  6. In Name, type a name for your class.

  7. In Modifiers, choose Public.

  8. Choose the Browse button beside Superclass. Superclass Selection appears, as shown in Figure 10-4.

    Superclass Selection

    Figure 10-4. Superclass Selection

  9. In Choose a type, type the name of the adapter class for the ROM element. For example, enter Label EventAdapter for the Label element. Choose OK. New Java Class reappears.

  10. Select Generate comments. Choose Finish. A Java editor view appears, similar to the one shown in Figure 10-5.

    The Java editor

    Figure 10-5. The Java editor

  11. Add the event handler method for your new event handler class. Figure 10-6 shows the addition of an onPrepare( ) method that sets the background color of the label to red.

    The onPrepare( ) method in the Java editor

    Figure 10-6. The onPrepare( ) method in the Java editor

Making the Java class visible to BIRT

One way to make a Java event handler class visible to the BIRT report designer is to create a Java development project for compiling the class in the same workspace as your BIRT report project. The other option is to place the class in a directory or JAR file that is specified in the BIRT classpath. When you deploy the report to an application server, however, you must copy the Java class to the appropriate location on the server. For more information about deploying Java classes to an application server, see the chapter about deploying BIRT to an application server.

Associating the Java event handler class with a report element

After you create the Java event handler class and code the appropriate handler methods, you must associate the class with the appropriate report element.

How to associate a Java class with a report element

The example in this procedure makes the following assumptions:

  1. The report design includes a scriptable report item, such as a label.

  2. A Java class containing event handler methods for the scriptable report item is visible to BIRT.

  1. In Outline, select the report element for which an event handler class is visible to BIRT, as shown in Figure 10-7.

    Selecting a report element

    Figure 10-7. Selecting a report element

  2. In Property Editor for the selected report element, select Event Handler and enter the fully qualified name of your event handler class, as shown in Figure 10-8.

    The event handler class name

    Figure 10-8. The event handler class name

BIRT Java interface and class naming conventions

When working with BIRT Java event handlers, you encounter event handler interfaces, adapter classes, element instance interfaces, and element design interfaces. All BIRT event handler classes and interfaces are named using consistent naming conventions.

Naming convention for event handler interfaces

All BIRT ROM element interface names begin with the letter I, which is followed by the name of the ROM element and then EventHandler. For example, the interface for the Label element is ILabelEventHandler.

Naming convention for event handler adapter classes

All BIRT ROM element adapter class names begin with the name of the element, followed by EventAdapter. For example, the name of the adapter class for a Label element is LabelEventAdapter.

Naming convention for ROM element instance interfaces

All BIRT ROM element instance interface names begin with the letter I, followed by the name of the element and then Instance. For example, the ROM element instance interface for a Label element is ILabelInstance.

Naming convention for ROM element design interfaces

All BIRT ROM element instance design interface names begin with the letter I, followed by the name of the element. For example, the design interface for a Label element is ILabel.

Writing a Java event handler

Most scriptable elements have more than one event for which you can write a handler. If you write an event handler for any event of an element, the event handler class must include methods for all the events for that element. You can leave empty those methods that do not require handler code but the empty methods must appear in the class.

You can give an event handler class any name you choose. You associate the class with a report element in BIRT Report Designer in the Properties view, as explained earlier in this chapter. Your Java event handler class can either extend an adapter class or implement an event handler interface. Adapter classes and handler interfaces are explained in the next sections.

Using event handler adapter classes

BIRT provides event handler adapter classes for every scriptable report element. An event handler adapter class contains empty methods for every event handler method for the element. If your class extends an adapter class, you need to override only the methods for the events for which you want to provide handler code.

One advantage of using an adapter class instead of implementing an interface is that your class will compile even if methods are added to the interface in a future release. If the signature of an event handler method changes in a future release, however, you must change your implementation of that method to reflect the signature change. The class will compile even if you do not change the method with the changed signature, but the method with the wrong signature will never be called.

Using event handler interfaces

BIRT provides event handler interfaces for every scriptable report element. If your event handler class extends an adapter class, the adapter class implements the correct interface. If your class does not extend an adapter class, then your class must implement the appropriate interface for the report element you are scripting.

There are some advantages of specifying an interface instead of extending an adapter class. Eclipse generates stubs for every method the interface specifies. The stubs show the method arguments, so you can see the argument types of the methods you must implement. If your class extends an adapter class, there are no generated stubs for you to examine. You also have more freedom in the design of your class structure if you avoid using an adapter class. For example, you might want two or more event handler classes to extend a single base class. Because Java does not support multiple inheritance, the event handler class cannot extend both the adapter class and the base class. However, if the event handler class implements an interface instead of extending an adapter class, there is nothing to prevent the event handler class from extending the base class.

The disadvantage of using an interface over an adapter class is that if additional methods are added to an interface in a future release, a class that implements the interface fails to compile.

About the Java event handlers for report items

You can write an event handler for any or all the events that BIRT fires for a report item. Table 10-1 describes the events BIRT fires for each report item.

Table 10-1. Report item event handler methods

Method

Description

onPrepare( )

The onPrepare( ) method for every report element contains the following two arguments:

  • The element design interface

  • The report context interface

onCreate( )

The arguments to the onCreate( ) method depend on the particular element. Every onCreate( ) method contains at least the following two arguments:

  • The element instance interface

  • The report context interface

onPageBreak( )

The onPageBreak( ) method for every report element contains the following two arguments:

  • The element instance interface

  • The report context interface

onRender( )

The onRender( ) method for every report element contains the following two arguments:

  • The element instance interface

  • The report context interface

Using Java event handlers for the DataSource element

The DataSource event handler interface has four methods that you can implement to respond to events. A Java class to handle these events must implement the IDataSourceEventHandler interface or extend the DataSourceAdapter class.

All the event methods receive an IReportContext object. All the methods except the afterClose( ) method also receive an IDataSetInstance object. The onFetch( ) method also receives an IDataSetRow object. These interfaces are discussed later in this chapter. Table 10-2 lists the four methods that you can implement for a DataSource element.

Table 10-2. DataSource event handler methods

Method

Description

beforeOpen( IDataSourceInstance dataSource, IReportContext reportContext )

The beforeOpen event fires immediately before opening the data source. This handler is often used to change the connection properties, such as user name and password.

afterOpen( IDataSourceInstance dataSource, IReportContext reportContext )

The afterOpen event fires immediately after opening the data source.

beforeClose( IDataSourceInstance dataSource, IReportContext reportContext )

The beforeClose event fires immediately before closing the data source.

afterClose( IReportContext reportContext )

The afterClose event fires immediately after closing the data source.

Using Java event handlers for the DataSet element

BIRT fires five events for the DataSet element. A Java class to handle these events must implement the IDataSetEventHandler interface or extend the DataSetAdapter class. All DataSet event handler methods receive an IReportContext object. Additionally, all DataSet event handler methods except the afterClose( ) method receive an IDataSetInstance object. The onFetch( ) method receives a third object, an IDataSetRow object. These interfaces are described later in this chapter. Table 10-3 lists the five methods that you can implement for a DataSet element.

Table 10-3. DataSet event handler methods

Method

Description

beforeOpen( IDataSetInstance dataSet, IReportContext reportContext )

The beforeOpen event fires immediately before opening the data set. This event handler is often used to change the query text for a data set.

afterOpen( IDataSetInstance dataSet, IReportContext reportContext )

The afterOpen event fires immediately after opening the data set.

onFetch( IDataSetInstance dataSet, IDataSetRow row, IReportContext reportContext )

The onFetch event fires upon fetching each row from the data source.

beforeClose( IDataSetInstance dataSet, IReportContext reportContext )

The beforeClose event fires immediately before closing the data set.

afterClose( IReportContext reportContext )

The afterClose event fires immediately after closing the data set.

Using Java event handlers for the ScriptedDataSource element

The ScriptedDataSource interface extends the IDataSourceEventHandler interface, which has four methods. The ScriptedDataSource interface adds two new methods to the four of the IDataSourceEventHandler interface. A Java class that provides the ScriptedDataSource event handlers must implement IScriptedDataSourceEventHandler interface or extend the ScriptedDataSourceAdapter class. A Java class that provides the ScriptedDataSource event handlers must implement the two methods of the IScriptedDataSourceEventHandler interface plus the four methods of the IDataSourceEventHandler interface, which it extends.

Both of the two event handler methods of IScriptedDataSourceEventHandler receive an IDataSourceInstance object. Table 10-4 lists the two additional methods that you must implement for a ScriptedDataSource element.

Table 10-4. ScriptedDataSource event handler methods

Method

Description

open( IDataSourceInstance dataSource )

Use this method to open the data source.

close( IDataSourceInstance dataSource )

Use this method to close the data source and perform cleanup tasks.

Using Java event handlers for the ScriptedDataSet element

The ScriptedDataSet interface extends the IDataSetEventHandler interface, which has four methods. The ScriptedDataSet interface adds four new methods to the four of the IDataSourceEventHandler interface. Of the four new methods, three must be fully implemented and the fourth may be empty. A Java class that provides the ScriptedDataSet event handlers must implement IScriptedDataSetEventHandler interface or extend the ScriptedDataSetAdapter class. A Java class that provides the ScriptedDataSet event handlers must implement the four methods of the IScriptedDataSetEventHandler interface plus the four methods of the IDataSourceEventHandler interface, which it extends.

Table 10-5 lists the four additional methods that you must implement for a ScriptedDataSet element.

Table 10-5. ScriptedDataSet event handler methods

Method

Description

open( IDataSetInstance dataSet )

Called when the data set is opened. Use this method to initialize variables and to prepare for fetching rows.

fetch( IDataSetInstance dataSet, IUpdatableDataSetRow dataSetRow )

Called at row processing time. Use this method to fetch data with which to populate the row object. This method must return true if the fetch is successful and false if it is not.

close( IDataSetInstance dataSet )

Called upon completion of processing a data set. Use this method to perform cleanup operations.

describe( IDataSetInstance dataSet, IScriptedDataSetMetaData metaData metaData )

Use this method to define the column names and types of the data set.

Using Java event handlers for the ReportDesign

BIRT fires several events that the ReportDesign element handles. A Java class to handle these events must implement the IReportEventHandler interface or extend the ReportEventAdapter class. All of the event handler methods receive an IReportContext object. The beforeFactory( ) method also receives an IReportDesign object. Table 10-6 lists the methods that you can implement for a ReportDesign element in the order in which they fire.

Table 10-6. ReportDesign event handler methods

Method

Description

initialize( IReportContext reportContext )

The initialize event is fired twice, once before the generation phase begins and once before the render phase begins.

beforeFactory( IReportDesign report, IReportContext reportContext )

The beforeFactory event is fired before the generation phase begins.

afterFactory( IReportContext reportContext )

The afterFactory event is fired after the generation phase ends.

beforeRender( IReportContext reportContext )

The beforeRender event is fired before the presentation phase begins.

afterRender( IReportContext reportContext )

The afterRender event is fired after the presentation phase ends.

Understanding the BIRT interfaces

A developer of Java event handlers needs to be familiar with several Java interfaces. Most of the handler method parameters and return values are Java interfaces rather than classes.

The most important Java interfaces for developing Java event handlers are:

  • The element design interfaces

  • The IReportElement interface

  • The element instance interfaces

  • The report context interfaces

  • The IColumnMetaData interface

  • The IDataSetInstance interface

  • The IDataSourceInstance interface

  • The IDataSetRow interface

  • The IRowData interface

About the element design interfaces

Every element has a unique element design interface. The element design is a Java interface that specifies methods for accessing and setting specific features of the element’s design. Every element design interface inherits methods from IReportElement.

About the methods for each report element

Besides the methods defined in IReportElement, each report element has methods that are only relevant for that report element. For example, ICell, the design interface for a Cell object, includes the following methods in addition to those defined in IReportElement:

  • getColumn( )

  • getColumnSpan( )

  • getDrop( )

  • getHeight( )

  • getRowSpan( )

  • getWidth( )

  • setColumn( int column )

  • setColumnSpan( int span )

  • setDrop( java.lang.String drop )

  • setRowSpan( int span )

In contrast, the methods for ITextItem, the design interface for a TextItem element, includes these additional methods:

  • getContent( )

  • getContentKey( )

  • getContentType( )

  • getDisplayContent( )

  • setContent( java.lang.String value )

  • setContentKey( java.lang.String resourceKey )

  • setContentType( java.lang.String contentType )

For a complete list of all the design interfaces, see the BIRT Javadoc. To access the Javadoc, choose BIRT Developer Guide→Reference in the online help.

About the IReportElement interface

The IReportElement interface is the base interface for all the report element interfaces. IReportElement has the following methods:

  • getComments( )

  • getCustomXml( )

  • getDisplayName( )

  • getDisplayNameKey( )

  • getName( )

  • getNamedExpression( java.lang.String name )

  • getParent( )

  • getQualifiedName( )

  • getStyle( )

  • getUserProperty( java.lang.String name )

  • setComments( java.lang.String theComments )

  • setCustomXml( java.lang.String customXml )

  • setDisplayName( java.lang.String displayName )

  • setDisplayNameKey( java.lang.String displayNameKey )

  • setName( java.lang.String name )

  • setNamedExpression( java.lang.String name, java.lang.String exp )

  • setUserProperty( java.lang.String name, java.lang.Object value )

For more information about the methods defined in the IReportElement interface, including the arguments and return values of all its methods, see the BIRT Javadoc in the BIRT online help.

About the element instance interfaces

The element instance interfaces are available at run time, but not at design time. They contain the run-time instance of the element. The element instance interface is passed to both onCreate( ), the generation phase event handler, and to onRender( ), the presentation phase event handler.

Through instance interfaces, you have access to a different set of properties than you do at design time. There is no superinterface from which all element instance interfaces inherit. Like the element design interface, the set of methods in the instance interfaces varies from element to element.

For example, ICellInstance, the Cell instance interface, contains the following methods:

  • getColSpan( )

  • getColumn( )

  • getRowSpan( )

  • setColSpan( int colSpan )

  • setRowSpan( int rowSpan )

By comparison, IRowInstance, the Row instance interface, contains these methods:

  • getBookmarkValue( )

  • getHeight( )

  • getStyle( )

  • setBookmark( )

  • setHeight( )

For a complete list of all instance interfaces, see the BIRT Javadoc in the BIRT online help.

Using the IReportContext interface

An object of type IReportContext is passed to all event handlers except those for ScriptedDataSource and ScriptedDataSet objects. The IReportContext interface includes the methods shown in Table 10-7.

Table 10-7. IReportContext interface methods

Method

Task

deleteGlobalVariable( java.lang.String name )

Removes a global variable created using the setGlobalVariable( ) method.

deletePersistentGlobalVariable( java.lang.String name )

Removes a persistent global variable created using the setPersistentGlobalVariable( ) method.

getAppContext( )

Retrieves the application context object as a java.util.Map object. The report application can use the application context object to pass any information that is application-specific.One example of information passed through an application context object is the HTTPSession object.

getGlobalVariable( java.lang.String name )

Returns the object saved with the setGlobalVariable( ) method. The string argument is the key with which the object was saved.

getHttpServletRequest( )

Returns the HttpServletRequest object associated with the URL requesting the report. The HttpServletRequest object provides access to the request URL and any parameters that are appended to the request.

getLocale( )

Returns the locale associated with the report execution or rendering task. This locale might be different from the local machine’s system or user locale.

getMessage( java.lang.String key )

Returns a message from the default properties file.

getMessage( java.lang.String key, java.util.Locale locale, java.lang.Object[] params )

Returns a message from the properties file for a specified locale, using a parameters array.

getMessage( java.lang.String key, java.lang.Object[] params )

Returns a message from the default properties file, using a parameters array.

getOutputFormat( )

Returns a string containing either html or pdf, depending on which format was specified in the __format parameter of the request URL.

getParameterValue( java.lang.String name )

Returns the value of the parameter named in the name argument. The value returned is a java.lang.Object.

getPersistentGlobalVariable( java.lang.String name )

Returns the serializable object saved with the setPersistentGlobalVariable( ) method. The string argument is the key with which the serializable object was saved.

setGlobalVariable( java.lang.String name, java.lang.Object obj )

Saves an object that can be retrieved in the same execution phase as it is saved. The setGlobalVariable( ) method takes a string argument and an Object argument. You use the string argument as a key with which to later retrieve the saved object.

setParameterValue( java.lang.String name, java.lang.Object value )

Sets the value of a named parameter with the value contained in the value parameter.

setPersistentGlobalVariable( java.lang.String name, java.io.Serializable obj )

Saves an object that can be retrieved in a different execution phase than it is saved. The setPersistentGlobalVariable( ) method takes a string argument and a serializable object argument. You use the string argument as a key with which to later retrieve the serializable object. The object is serializable because it must be persisted between phases to support executing the two phases at different times and possibly on different machines. The serializable object is saved in the report document.

Using the IColumnMetaData interface

The IColumnMetaData interface provides information about the columns of the data set. Table 10-8 lists the methods in the IColumnMetaData interface class.

Table 10-8. IColumnMetaData interface methods

Method

Returns

getColumnAlias( int index )

The alias assigned to the column at the position indicated by the index argument

getColumnCount( )

The count of columns in the data set

getColumnLabel( int index )

The label assigned to the column at the position indicated by the index argument

getColumnName( int index )

A string containing the name of the column at the position indicated by the index argument

getColumnNativeTypeName( int index )

The name of the type of data in the column at the position indicated by the index argument

getColumnType( int index )

The data type of the column at the position indicated by the index argument

getColumnTypeName( int index )

The name of the type of data in the column at the position indicated by the index argument

isComputedColumn( int index )

True or false, depending on whether the column at the position indicated by the index argument is a computed field

Using the IDataSetInstance interface

The IDataSetInstance interface provides access to many aspects of the data set and associated elements. An IDataSetInstance object is passed to every DataSet event handler method.

Table 10-9 describes the methods in the interface IDataSetInstance.

Table 10-9. IDataSetInstance interface methods

Method

Returns

getAllExtensionProperties( )

The data set extension properties in the form of a java.util.Map object. The map object maps data extension names to their values.

getColumnMetaData( )

An IColumnMetaData object that provides the data set’s metadata.

getDataSource( )

A DataSource object with which the data set is associated.

getExtensionID( )

The unique ID that identifies the type of the data set, assigned by the extension that implements this data set.

getExtensionProperty( java.lang.String name )

The value of a data set extension property.

getName( )

The name of this data set.

getQueryText( )

The query text of the data set.

setExtensionProperty( java.lang.String name, java.lang.String value )

The value of an extension property.

setQueryText( java.lang.String queryText )

The query text of the data set.

Using the IDataSetRow interface

An object of the IDataSetRow type is passed to the DataSet.onfetch( ) event handler method. Table 10-10 lists the methods in the IDataSetRow interface. Note that there are two getColumnValue( ) methods. The two methods differ only in the argument that specifies the column containing the value. They both return a java.lang.Object object, which you must cast to the appropriate type for the column.

Table 10-10. IDataSetRow interface methods

Method

Returns

getColumnValue( int index )

The column data by index. This index is 1-based.

getColumnValue( java.lang.String name )

The column data by column name.

getDataSet( )

An IDataSetInstance object representing the data set that contains this row.

Using the IRowData interface

An object of the IRowData type is returned from the getRowData( ) method of IReportElementInstance, which every report element instance interface extends.

IRowData provides access to the bound values that appear in the table. The IRowData interface has two getExpressionValue( ) methods. Both methods return the display value for a specific column in the table. The two methods differ in the argument you pass to specify the column that you require. Table 10-11 lists the methods in the IRowData interface.

Table 10-11. IRowData interface methods

Method

Returns

getColumnCount( )

Return the count of the bounding expressions.

getColumnName( int index)

Return the name of the bounding expression by id.

getColumnValue(int index)

Return the value of the bounding expression by id. This index is 1-based.

getColumnValue(String name)

Return the value of the bounding expression by name.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset