The BIRT ODA extension point
Extend BIRT's data-retrieval capabilities
The extensibility of the Business Intelligence Reporting Tools (BIRT) is one reason it is a powerful reporting platform. Built on top of Eclipse, BIRT uses the Eclipse plug-in framework to enhance and extend its capabilities. Several different extension points are defined in BIRT. The more prominent extension points include:
- Open Data Access (ODA) framework for retrieving data
- Report item extension point for adding new report items to BIRT's palette
- Emitter framework for expanding BIRT's output capabilities
- Function script library for extending BIRT's helper methods in BIRT script and in BIRT expressions
- Aggregation extension point, which allows users to aggregate values of a data set
In previous articles I covered the aggregation and the emitter frameworks (see Related topics for links). This article focuses on one of the other heavily used extension points, the Eclipse Data Tools Platform (DTP) ODA framework. ODA is a BIRT framework that you can use to extend BIRT's data-retrieval capabilities. Knowing this framework allows system integrators to extend BIRT beyond the realm of strictly database reporting. By writing different emitters, BIRT extends to report on flat files, Plain Old Java™ Objects, indexed data stores used for high-speed search applications such as Apache Solr and Lucene search, and to work directly with IBM® Maximo® data application programming interfaces (APIs), and big data sources such as Apache Hadoop and other MapReduce-based storages.
Understand the data extraction task
In this example, you use the BIRT Report Engine API data extraction task to retrieve data. You use the data extraction task to extract data from a previously run BIRT report by retrieving the data from BIRT's report document file. The task requires the name of a report document and the name of a table with a data set binding. This task allows an application to use a report document as a temporary cache that contains all the bindings, expressions, and aggregations. You can then apply sorts during the retrieval process.
By writing an ODA that can retrieve data from a report document file, you can write reports against existing reports, opening a whole new set of possibilities for the open source BIRT, such as run-once data sets that you can reuse for multiple reports.
ODA architecture in BIRT
Writing ODA plug-ins for BIRT can be a complicated matter. There are two types of plug-ins to write: a runtime data plug-in and a design-time user interface (UI) plug-in. Let's consider the runtime plug-in first. Like many other BIRT extension points, the ODA extension classes use an observer-based design pattern. But what is different about the ODA architecture is that several of the observed calls are actually factory calls, requiring the observer to create new objects that are themselves observers. BIRT's internal data engine serves as the observed object, and the developer is responsible for creating the observer. Using the plug-in and manifest Extensible Markup Language (XML) files, the plug-in registers itself as an observer with the data engine.
At a high level, a few basic types of factories create observers. The factories must generate observers for data source connections, data set queries, parameters, and result sets (see Figure 1).
Figure 1. High-level diagram of the observer/observed/factory patterns that are used with BIRT ODA
Create a new runtime plug-in project
To create a runtime plug-in project, follow these steps:
- In Eclipse, click File > New > Other.
- On the Select a wizard page, expand Plug-in
Development, and then select Plug-in
Project (see Figure 2). Click
Figure 2. Select the plug-in project type
- On the Plug-in Project page, in Project
com.digiassn.blogspot.birt.oda.reportDocument(see Figure 3), and then click Next.
Figure 3. Name the project
- On the Content page, fill out the properties as shown
in Figure 4. Make note of the ID, then click
Figure 4. Assign properties to the project
- On the Templates page, in the Available
Templates box, select ODA Data Source Runtime
Driver (see Figure 5). Click
Figure 5. Assign a template to the plug-in
- On the next page, you set the specific plug-in information. Set the properties for the data source to 1 to use for the report document file name and 0 for the data set. Click Finish.
The ODA Data Source Runtime Driver wizard creates all the observer classes that are needed to write the plug-in.
Configure the plug-in
If you followed all of the steps in the wizard, you already set most of the
configuration items. The remaining items to work with are the
driverClass and the properties.
To configure the plug-in, follow these steps:
- Open the plugin.xml file to open the manifest editor, which is shown
in Figure 6.
Figure 6. Configure the plugin.xml file in the manifest editor
- At the bottom of the editor, click the Extensions tab
(see Figure 7).
Figure 7. The manifest editor Extensions tab
- In the All Extensions box, expand
until you see the (properties) section, which you use
to pass in data source parameters. For this ODA, it passes in a report
document file name. Rename this item from
ReportDocument, as shown in Figure 8.
Figure 8. Rename the property for your plug-in
(View a larger version of Figure 8.)
- Click the dataSource leaf node in the editor to open
the properties for the ODA, and verify that the
driverClassproperty is set. (Clicking the hyperlink opens the
Class structure of the runtime driver
Driver class is the root observer for the
ODA. It serves as a factory object that creates the
Connection object. If you are using the wizard,
Connection object most of the boilerplate
code is already written, but you complete the implementations of these
methods. However, the
Connection object has a
few methods for you to modify. The
is one of the methods observed that you must override. It is responsible
for opening the data connection to the data source. For a Java Database
Connectivity (JDBC) database connection,
would open a connection to the database. However, the report document ODA
in this example uses the BIRT Report Engine API to open the report
document file that is reported on. The
Connection object also serves as a factory for
IQuery objects through the
IQuery method follows this same pattern of
being both an observer and a factory. The observer method that you must
overwrite is the
prepare() method, which is
responsible for preparing the
IQuery method for
execution. For a database query, you use a Structured Query Language
query. The report document ODA, contains the name of the data set that is
stored inside the report document, which is supplied by the design plug-in
and stored in the report design for execution. The second method to
overwrite is the factory method
which returns an
Continuing the observer/factory pattern that other objects use, the
IResultSet object is responsible for iterating
over the results from a query and retrieving the column values from both a
numeric index and a named column. You use the
next() method to iterate over each row in the
result set. The method returns true if there are remaining rows
and false if there are no other rows to return. In the report
document ODA, this method calls the BIRT Data Extraction Task's
next() method. You must write each of the
get column methods and
get data type methods. A
getMetaData() method returns the metadata of
the column types. BIRT uses this metadata object to track the types and
uses that information as a map to call the
getType(columnName) method. Depending on the
data source you retrieve, you can override the
close() method in the
IResultSet, as well. For a database, this
override closes the JDBC
ResultSet object. For
the report document ODA, this method closes the Data Extraction Task's
result set iterator and sets all objects to null.
That roughly describes all the objects that are used in the runtime plug-in. The complete source for the plug-in is available in Download.
Design time UI plug-in
The design time UI plug-in is not required, but it is helpful. If you don't create a design time UI plug-in, BIRT provides prompts for the properties that are defined in the plugin.xml and manifest files.
To create the design time UI plug-in, follow these steps:
- Create a new plug-in project, as you did earlier, and then click Next.
- Give the project a name, identifying it as a UI plug-in (see Figure 9), and then click Next.
Figure 9. Name the UI plug-in project
- On the Content wizard page, select the This plug-in makes contributions to the UI check box; otherwise, the wizard option for ODA UI plug-ins is not available. Click Next.
- On the Templates wizard page, in the
Available Templates box, select ODA Data
Source Designer, as shown in Figure
10. Click Next.
Figure 10. Assign the ODA Data Source Designer template to the plug-in
- On the ODA Data Source Designer wizard page that is
shown in Figure 11, verify that the IDs for the
ODA runtime driver plug-in, data source element, driver class, and the
data set element ID match what was set in the runtime project. If you
want to change these items after the wizard is complete, you can
modify the values through the manifest editor or set the variables for
the IDs in the plugin.properties file.
Note: Pay attention to that little tidbit about the plugin.properties file: When I first started ODA development, I wasted time looking for it.
Figure 11. Review the properties in the ODA Data Source Designer
Creating the pages for the data source and data set editors is a simple
matter of registering property pages in the manifest editor, and then
creating Standard Widget Toolkit (SWT) composites. Each page extends the
DataSetWizardPage, depending on what type of
page it is.
DataSourceWizard pages are the
property pages that are used during the first execution of a new data
source in BIRT. Likewise, the
is the first page that is used in data set creation. The
DataSourceWizardPage creates a custom
properties composite from the
createPageCustomControl() method. The composite
that is created calls the
to move to the next wizard page. It also calls the
method with the appropriate properties set. Remember that editing a data
source editor when you click a data source in the BIRT editor does not
call this same set of classes: It calls a separately defined property
page. The definition for both can be seen in the
newDataSourceWizard and the designer data
source connection properties in the manifest editor. In the example code,
the RptDocPropertyPage.java file for editing an existing data source calls
CustomPropertiesPage that the new data
source wizard does.
I described a mostly straightforward Eclipse view development. You might want to explore the no cost WindowBuilder Pro from Instantiations/Google (see Related topics for a link). The SWT designer goes a long way in easing the development of the layouts of views.
This article walked you through the process of creating two plug-in projects—one for design time and one for runtime. These plug-ins are fairly complex, but by referencing the example project, you can extend BIRT's data-retrieval capabilities. In addition, the plug-in shows you how to use the BIRT engines data extraction task to extract data from existing BIRT report document files.
- Using the BIRT Project emitter extension point (developerWorks, September 2012): See John's previous article to learn more about the emitter extension point.
- Using Eclipse BIRT extension points (developerWorks, December 2009): See John's previous article to learn more about the aggregation extension point.
- The Digital Voice: Check out John's personal technology and tutorial blog.
- Apache Solr: Learn more about Solr, Apache's open source enterprise search platform.
- Apache Lucene: Written entirely in Java, Lucene is Apache's high-performance, full-featured text search engine library.
- Apache Hadoop: Learn more about the Hadoop project.
- IBM Maximo: Discover Maximo, IBM's enterprise asset-management tool.
- WindowBuilder Pro: Recently contributed to Eclipse, WindowBuilder Pro is a powerful WYSIWYG designer for designing Eclipse GUIs.
- BIRT Project: Download BIRT from eclipse.org.
- Evaluate IBM products: Evaluate products in the way that suits you best: Download a product trial, try a product online, use a product in a cloud environment, or spend a few hours in the SOA Sandbox learning how to implement service-oriented architecture efficiently.