JReport Data Source Driver

1. Introduction

2. Data Source API

2.1 Background
2.2 JRColDesc
2.3 JRResultSet
2.4 JRResultSetException

3. Use Data Source Driver

3.1 Configure Data Source Driver in Designer
3.2 Data Source Driver URL Syntax
3.3 Driver File

4. Example


1. What is the Data Source API?

As a database application, JReport requires the ability to access data. JReport can access data stored in a database through the JDBC connection. In addition, JReport can also access data from user's application through a Data Source Driver.

The Data Source Driver described in this document is designed to extend JReport's ability of accessing data. Using the Data Source Driver, users can  produce report by providing data from user's programs or any external sources.

The Data Source Driver is a Java class that provides the data set to JReport when the report is generated at the runtime.  Normally, the report engine gets the report data set from the JDBC calls with the SQL statements.  When the report uses the Data Source Driver, the report engine gets the data set from the Data Source Driver.  In other words, the Data Source Driver is an alternative to the JDBC calls.

The Data Source Driver class must be written according to JReport's Data Source API specification. The Data Source API includes some JDBC classes and three JReport classes.

The Data Source Driver class inherits the abstract driver class in JReport, and uses JDBC classes and JReport classes to communicate with JReport. The Data Source Driver class also implements the methods that provide data access.  In addition, the Data Source Driver could have runtime arguments like command line arguments. This makes the Data Source Driver more configurable.

After the Data Source Driver is completed, the user needs to register the driver to JReport and specify the driver to be used in each report.  User must specify the directory where the driver class is located before running the report using the Data Source Driver.

2. Data Source API

The Data Source API is a subset of the JDBC API.  The advantage is the user can build his driver by writing only one class. The disadvantage is that it can not be a total replacement for JDBC. In particular, since the user does not need to provide all the meta-data methods to specify the data type of each data field, the user needs to set up a "dummy" JDBC data source while designing the report.

In JReport, the JReport Engine needs a data set to produce report.  The JDBC receives an SQL statement and returns a result set to JReport Engine.  The Data Source Driver simulates this JDBC interface and returns a result set without the need for an SQL statement.  When JReport engine needs a result set, it will create an instance of the Data Source Driver, initialize the driver by an array of column descriptions and an array of arguments. After the driver is initialized, JReport will fetch data from the driver in the same fashion as from a JDBC driver.

The array of columns describes the columns in the result set.  The array of arguments transfer the run time arguments to the driver.  The driver will provide the data set via the set of functions defined in the API.

2.1 Background

Data Source API is a subset of JDBC and it uses many concepts and classes of JDBC. So some knowledge of JDBC is needed to use Data Source API and build your own Data Source Driver.

In this section, we will provide some references of JDBC. If you are familiar with JDBC, you can skip to the next section.

About mapping SQL types and Java types, please refer to the document JDBCTM Guide: Getting StartedThe chapter on Mapping SQL and Java Types is replicated here.

The JDBC classes include:

java.sql.Types - The class that contains many constants with sql type. It is used in the column description.

java.sql.Date - The class that represents the data value in the data set. The driver needs to return the instance of this class.

java.sql.Time - The class that represents the time value in the data set. The driver needs to return the instance of this class.

java.sql.TimeStamp - The class that represents the timestamp value in the data set. The driver needs to return the instance of this class.

java.sql.ResultSet - The interface that contains many methods that provide the access of data set.   JRResultSet implements the interface. The user Data Source Driver provides some of the methods.

2.2 JRColDesc

The JRColDesc describes the data column in the data set. The column name, sql type, precision, scale and nullable. See API documentation.

2.3 JRResultSet

The JRResultSet is an abstract class that provides methods for fetching data in a data set. The JRResultSet implements the interface java.sql.ResultSet and marks the relevant method as abstract. The input of the class is the description of the columns and arguments and the output of the class is the data set. The user Data Source Driver will inherit the JRResultSet and provide all the abstract methods.

When the Data Source Driver is initialized, the description of  the columns is passed to the method initialize and it describes the columns in the data set. The description is kept in an array and the index of the array is the column index.  The column index is used in the get??? method.

The following is the API documentation of JRResultSet.


Class jet.datasource.JRResultSet

 o 01 JRResultSet

 public JRResultSet()
Constructs an uninitialized JRResultSet.

 o 02 initialize

 public abstract void initialize(JRColDesc colDescs[],

                                 String args[]) throws JRResultSetException
Initialize this JRResultSet.
The initialize method is called after the class constructed.
Parameters:
colDescs - the descriptions of columns in the result set.
args - the arguments of this class.
Throws: JRResultSetException
when a data source error occurs.

 o 03 next

 public abstract boolean next() throws JRResultSetException
Fetches a new row of data and returns true if it is OK.
Returns:
false if no more data.
Throws: JRResultSetException
when a data source error occurs.

 o 04 close

 public abstract void close() throws JRResultSetException
Close the JResultSet and release the resources.
It is the last call in the Data Source API when JReport finishes generating the report.
Throws: JRResultSetException
when a data source error occurs.

 o 05 wasNull

 public abstract boolean wasNull() throws JRResultSetException
To judge whether the last column read had NULL value.
Returns:
true if last column read was SQL NULL.
Throws: JRResultSetException
when a data source error occurs.

 o 06 getString

 public abstract String getString(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java String.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value as Java String.
Throws: JRResultSetException
if a data source error occurs.

 o 07 getBoolean

 public abstract boolean getBoolean(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java boolean.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL, return false.
Throws: JRResultSetException
if a data source error occurs.

 o 08 getByte

 public abstract byte getByte(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java byte.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return 0.
Throws: JRResultSetException
if a data source error occurs.

 o 09 getShort

 public abstract short getShort(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java short.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return 0.
Throws: JRResultSetException
if a data source error occurs.

 o 10 getInt

 public abstract int getInt(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java int.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return 0.
Throws: JRResultSetException
if a data source error occurs.

 o 11 getLong

 public abstract long getLong(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java long
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return 0.
Throws: JRResultSetException
if a data source error occurs.

 o 12 getFloat

 public abstract float getFloat(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java float.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return 0.
Throws: JRResultSetException
if a data source error occurs.

 o 13 getDouble

 public abstract double getDouble(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a Java double.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return 0.
Throws: JRResultSetException
if a data source error occurs.

 o 14 getBigDecimal

 public abstract BigDecimal getBigDecimal(int columnIndex,

                                          int scale) throws JRResultSetException
Get the value of a column in the current row as a java.lang.BigDecimal object.
Parameters:
columnIndex - the index number of the column.
scale - the number of digits to the right of the decimal.
Returns:
the column value, if the value is NULL,return null.
Throws: JRResultSetException
if a data source error occurs.

 o 15 getDate

 public abstract Date getDate(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a java.sql.Date object.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return null.
Throws: JRResultSetException
if a data source error occurs.

 o 16 getTime

public abstract Time getTime(int columnIndex) throws JRResultSetException

Get the value of a column in the current row as a java.sql.Time object.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return null.
Throws: JRResultSetException
if a data source error occurs.

 o 17 getTimestamp

 public abstract Timestamp getTimestamp(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a java.sql.Timestamp object.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return null.
Throws: JRResultSetException
if a data source error occurs.

 o 18 getBinaryStream

 public abstract InputStream getBinaryStream(int columnIndex) throws JRResultSetException
Get the value of a column in the current row as a stream of uninterpreted bytes, then this column value can be read in chunks from the this stream.
Parameters:
columnIndex - the index number of the column.
Returns:
the column value, if the value is NULL,return null.
Throws: JRResultSetException
if a data source error occurs.

2.4 JRResultSetException

The exception is used when a data source error occurs in the Data Source Driver.

See API documentation

3. Use Data Source Driver

When a Data Source Driver is provided by the user, the driver should be registered with JReport before it is used to run a report. To register the Data Source Driver, the user need to specify the following:

1. Driver Name:

The driver name is the name that you give to your Data Source Driver. You will use this name in JReport Designer to define which Data Source Driver you will use in a report. The driver name is case-insensitive and the equal sign ("=") is a reserved character in the driver name.

2. Class Name:

The class name is the qualified class name of the Data Source Driver.  It is used to load the specified class.

The qualified class name is defined by the java language.  The following text is quoted from the java document:

"The fully qualified name of a named package that is a subpackage of another named package consists of the fully qualified name of the containing package, followed by ".", followed by the simple (member) name of the subpackage.

The fully qualified name of a class or interface that is declared in an unnamed package is the simple name of the class or interface.

The fully qualified name of a class or interface that is declared in a named package consists of the fully qualified name of the package, followed by ".", followed by the simple name of the class or interface."

For definitive information on fully qualified class name, please see Java Language Specification (6.7)

3. Arguments

The arguments for the user Data Source Driver. The arguments will be passed to the initialize method of Data Source Driver. You do not need to provide the arguments if you did not use it in your Data Source Driver.

3.1 Configure Data Source Driver in JReport Designer.

3.1.1. Register Data Source Driver

User can register the their own Data Source Driver with JReport. JReport can hold more than one drivers in its registry. The data source manager dialog is used to add, remove and modify the Data Source Driver registry.

Data Source Driver Manager

In Catalog Browser, click on the Data Source Manage buttondatasourceButton.gif (1094 bytes). The Data Source Driver Manager will appear:

User Data Source Drivers list

A list of all user Data Source Driver names. Double-clicking a driver name displays the Data Source Driver editor dialog box.

Data Source Driver Editor

When the user adds a new driver or edits an exist driver, the Data Source Driver Editor window will be shown:

datasourceAPI2.gif (14794 bytes)

3.1.2. Specifying the Data Source Driver for a Report.

To use the Data Source Driver, you need to specify the driver in the report. You can specify the driver either in the designer window or in the report inspector.

Designer Window

datasourceAPI3.gif (39678 bytes)

In the designer window, there is a drop down list on the right of the second (edit) toolbar.  The drop down list displays all the names of Data Source Drivers for the current report.  The default driver is CatalogQuery.   Select the name of your driver to specify the Data Source Driver for this report.

If CatalogQuery is selected, JReport will use the internal data source which connects to a DBMS via JDBC.

Report Inspector

datasourceAPI4.gif (13483 bytes)

You can also specify the Data Source Driver used by a report using the report inspector.

  1. Select the menu View|Report Inspector to show the Report Inspect window.
  2. Select the report object on the object tree.  The report object is the top-level object.
  3. Select and expend the others property group in the properties sheet.
  4. There is a property in report object called DataDriver, in which you can either select a driver from a list, or type the driver URL directly. If the DataDriver is CatalogQuery or blank, JReport will use the internal data source which connects to a DBMS via JDBC.

3.2 Data Source Driver URL Syntax

The URL describes a Data Source Driver. It is composed of three parts: scheme, qualified class name and arguments. If the Data Source Driver does not use argument, then the argument part will not appear on the URL.

jrquery:/JRResultSetSample

Below is the syntax of Data Source Driver URL:

URL  = "jrquery" ":" "/" qualified_classname[ ";" params]
params  = param * (";" param)
param  = *( pchar | "/" )
pchar  = uchar | ":" | "@" | "&" | "="
uchar  = alpha | digit | safe | extra
alpha = lowalpha | hialpha
lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" |
                "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" |
                "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"
hialpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" |
              "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" |
              "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"
digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"
safe = "$" | "-" | "_" | "." | "+"
extra = "!" | "*" | "'" | "(" | ")" | ","
reserved = ";" | "/" | "?" | ":" | "@" | "&" | "="

The syntax of the JReport Data Source Driver definition is designed according to the URL syntax.   For definitive information on URL syntax and semantics, see RFC 1738 [4] and RFC 1808 [11].

3.3 Drivers File

The registered Data Source Drivers are kept in a file named jrdata.drv. This file is normally located in the bin subdirectory under the install directory of JReport.  In the file, each line is treated as a driver definition.

The following is the content of an example jrdata.drv file.

mydriver=jrquery:/jet.univers.a;a;b;c
jreportsetample=jrquery:/JRResultSetSample

4. Example

In the following example, the class JRResultSetSample inherits from jet.datasource.JRResultSet and provides methods to access  data.  The source code JRResultSetSample.java shows you how to create a Data Source Driver.

First, place the class file in a directory, and add the directory to the classpath environment variable.

Second, Register the driver to JReport.

  1. Run JReport Designer
  2. Select menu View|Catalog Browser.
  3. Click the data source manager button on the catalog browser.
  4. Click the Add button.
  5. Specify the driver name and definition on the Data Source Driver editor dialog and Click OK.

datasourceAPI2.gif (14794 bytes)

Then open the report that uses the Data Source Driver, select the driver name on the drop down list on the toolbar.

After all of the steps are done, the report is ready to be generate using the example Data Source Driver.