Driver Bridge Extension Point
The DTP project provides a driver bridge extension point that is very useful in BIRT projects, since it allows calls made to the data source layer to be intercepted and manipulated. This feature can be used for many purposes, such as providing a customized connection-pooling algorithm, modifying a query before running it, adding a privilege check, or ignoring any call that a specific JDBC driver doesn't support. This extension point can be used with other data sources, but this example focuses primarily on the JDBC driver.
Suppose you need to change a query executed by the JDBC driver if the query is selecting from an order details table. If the report doesn't specify a WHERE clause, the plug-in needs to add a mandatory WHERE clause to the executing SQL.
Listing 6 shows the plugin.xml code required to implement this extension point.
Listing 6
<?xml version="1.0" encoding="UTF-8"?> <?eclipse version="3.2"?> <plugin> <extension id="org.eclipse.birt.report.data.testjdbc" point="org.eclipse.datatools.connectivity.oda .consumer.driverBridge"> <bridge driverType="org.eclipse.birt.report.data.oda.jdbc.OdaJdbcDriver" bridgeId="org.eclipse.birt.report.data.changequery"> </bridge> </extension> <extension point="org.eclipse.datatools.connectivity.oda.dataSource"> <dataSource odaVersion="3.0" driverClass="org.eclipse.birt.report.data.changequery .MyJdbcDriver" defaultDisplayName="Sample Driver Bridge" setThreadContextClassLoader="false" id="org.eclipse.birt.report.data.changequery"/> <dataSet defaultDisplayName="%dataset.query.sqltype" id="org.eclipse.birt.report.data.oda.jdbc.JdbcSelectDataSet"> <dataTypeMapping nativeDataType="BIT" nativeDataTypeCode="-7" odaScalarDataType="Integer"/> </dataSet> </extension> </plugin>
The driverBridge extension point contains two nodes: driverType and bridgeId. The driverType defines the data source type to override. The bridgeId specifies the plug-in id for the plug-in that does the overriding.
While the Open Data Access (ODA) specification is beyond the scope of this article, understand that the entry point for any ODA driver is the driver Class. In this example, you must extend the JDBC OdaJdbcDriver class to use the driver, which is why the application contains a definition in the driver bridge plug-in for the org.eclipse.datatools.connectivity.oda.dataSource extension point.
In the example, the MyJdbcDriver Class is the extended OdaJdbcDriver class. The dataSet node is in the plugin.xml to allow validation of the XML. Its value is set to the default JdbcSelectDataSet.
Listing 7 contains the code for the MyJdbcDriver class.
Listing 7
package org.eclipse.birt.report.data.changequery; import org.eclipse.birt.report.data.oda.jdbc.*; import org.eclipse.datatools.connectivity.oda.IConnection; import org.eclipse.datatools.connectivity.oda.OdaException; public class MyJdbcDriver extends OdaJdbcDriver { public IConnection getConnection(String connectionClassName) throws OdaException { return new MyConnection(); } }
The code overrides the getConnection method in the JDBC driver to provide an overridden definition of the Connection class. Listing 8 shows the code for the MyConnection class.
Listing 8
package org.eclipse.birt.report.data.changequery; import org.eclipse.datatools.connectivity.oda.IQuery; import org.eclipse.datatools.connectivity.oda.OdaException; public class MyConnection extends org.eclipse.birt.report.data.oda.jdbc.Connection { public MyConnection() { } @Override public IQuery newQuery( String dataSourceType ) throws OdaException { return new MyStatement( jdbcConn ); } }
The MyStatement class extends the Statement class. MyStatement uses the overridden Connection class to execute the query in the newQuery method.
Listing 9 shows the code for the MyStatement class.
Listing 9
package org.eclipse.birt.report.data.changequery; import java.sql.Connection; import org.eclipse.birt.report.data.oda.jdbc.Statement; import org.eclipse.datatools.connectivity.oda.OdaException; public class MyStatement extends Statement { public MyStatement(Connection connection) throws OdaException { super(connection); } @Override public void prepare(String command) throws OdaException { if(( command.indexOf("from orderdetails") > 0 ) && (command.indexOf("where") <= 0 )){ command = command + " where ordernumber = 10101"; } super.prepare(command); } }
The MyStatement Class only overrides one method, which is the prepare method. This method is called by the ODA framework to prepare a query and receives the statement to execute. If the command to be executed contains no where clause, this method automatically appends the string WHERE ordernumber = 10101 to the statement before calling the super.prepare method of the JDBC data source. Figure 8 shows the output.
Figure 8 Example output.
Refer to the earlier section "Exporting and Deploying an Extension Point Plug-in" for information on how to deploy the driver bridge extension.