Creating the Hibernate ODA driver plug-in project
Create the Hibernate ODA driver plug-in project, org.eclipse.birt.report.data.oda.hibernate, using the New Plug-in Project wizard in the Eclipse PDE.
How to create the Hibernate ODA driver plug-in project
1 From the Eclipse PDE menu, choose FileNewProject.
2 In New Project—Select a wizard, open Business Intelligence and Reporting Tools and select ODA Runtime Driver Plug-in Project. Choose Next. New Plug-in Project appears.
3 In Plug-in Project, modify the settings as shown in Table 20‑8. Choose Next.
Table 20‑8 Settings for the Hibernate ODA plug-in project options
Section
Option
Value
Plug-in Project
Project name
org.eclipse.birt.report.data.oda.hibernate
 
Use default location
Selected
 
Location
Not available when you select Use default location
Project Settings
Create a Java project
Selected
 
Source folder name
src
 
Output folder name
bin
Target Platform
Eclipse version
3.5 or greater
 
OSGi framework
Deselected
Working Sets
Add project to working sets
Not selected
4 On Plug-in Content, modify the settings as shown in Table 20‑9.
Table 20‑9 Settings for the Hibernate ODA plug-in content options
Section
Option
Value
Properties
ID
org.eclipse.birt.report.data.oda.hibernate
 
Version
2.0.0
 
Name
BIRT ODA-Hibernate Driver
 
Vendor
yourCompany.com or leave blank
 
Execution Environment
JavaSE-1.7
Options
Generate an activator, a Java class that controls the plug-in’s life cycle
Selected
 
Activator
org.eclipse.birt.report.data.oda.hibernate.Activator
 
This plug-in will make contributions to the user interface
Deselected
 
Enable API Analysis
Deselected
Rich Client Application
Would you like to create a 3.x rich client application?
No
Choose Next.
5 In Templates, choose ODA Data Source Runtime Driver. Choose Next.
6 In ODA Data Source Runtime Driver, specify values for the following options used to generate the ODA plug-in, as shown in Table 20‑10.
Table 20‑10 Settings for the ODA data source run‑time driver options
Option
Value
Java Package Name
org.eclipse.birt.report.data.oda.hibernate
ODA Data Source Element Id
org.eclipse.birt.report.data.oda.hibernate
Data Source Display Name
Hibernate Data Source
Number of Data Source Properties
2
Data Set Display Name
Hibernate Data Set
Number of Data Set Properties
0
Choose Finish. After a few moments of processing, the Hibernate ODA driver plug-in project appears in the Eclipse PDE Workbench.
How to specify the properties of the Hibernate ODA plug-in project
1 Using the Eclipse PDE Manifest Editor, in Dependencies, specify the following required plug-ins in the following order:
*org.eclipse.core.runtime
*org.eclipse.datatools.connectivity.oda
*org.eclipse.birt.report.data.oda.jdbc
2 On Runtime, in Classpath, add the following JAR files to the plug-in classpath:
*odahibernate.jar
*lib/ant-antlr-1.6.5.jar
*lib/antlr-2.7.6rc1.jar
*lib/asm.jar
*lib/asm-attrs.jar
*lib/cglib-2.1.3.jar
*lib/commons-collections-2.1.1.jar
*lib/commons-logging-1.0.4.jar
*lib/dom4j-1.6.1.jar
*lib/ehcache-1.1.jar
*lib/hibernate3.jar
*lib/jta.jar
These JAR files must have been previously imported into the lib directory in the Hibernate ODA plug‑in. These JAR files can also be put in a new plug-in that the Hibernate ODA plug-in references.
3 In Runtime, in Exported Packages, use Add and verify that the following packages that the plug-in exposes to clients appear in the list:
*antlr
*antlr.actions.cpp
*antlr.actions.csharp
*antlr.actions.java
*antlr.actions.python
*antlr.ASdebug
*antlr.build
*antlr.collections
*antlr.collections.impl
*antlr.debug
*antlr.debug.misc
*antlr.preprocessor
*javax.transaction
*javax.transaction.xa
*net.sf.cglib.beans
*net.sf.cglib.core
*net.sf.cglib.proxy
*net.sf.cglib.reflect
*net.sf.cglib.transform
*net.sf.cglib.transform.hook
*net.sf.cglib.transform.impl
*net.sf.cglib.util
*net.sf.ehcache
*net.sf.ehcache.config
*net.sf.ehcache.hibernate
*net.sf.ehcache.store
*org.apache.commons.collections
*org.apache.commons.collections.comparators
*org.apache.commons.collections.iterators
*org.apache.commons.logging
*org.apache.commons.logging.impl
*org.apache.tools.ant.taskdefs.optional
*org.dom4j
*org.dom4j.bean
*org.dom4j.datatype
*org.dom4j.dom
*org.dom4j.dtd
*org.dom4j.io
*org.dom4j.jaxb
*org.dom4j.rule
*org.dom4j.rule.pattern
*org.dom4j.swing
*org.dom4j.tree
*org.dom4j.util
*org.dom4j.xpath
*org.dom4j.xpp
*org.hibernate
*org.hibernate.action
*org.hibernate.cache
*org.hibernate.cache.entry
*org.hibernate.cfg
*org.hibernate.classic
*org.hibernate.collection
*org.hibernate.connection
*org.hibernate.context
*org.hibernate.criterion
*org.hibernate.dialect
*org.hibernate.dialect.function
*org.hibernate.engine
*org.hibernate.engine.query
*org.hibernate.engine.transaction
*org.hibernate.event
*org.hibernate.event.def
*org.hibernate.exception
*org.hibernate.hql
*org.hibernate.hql.antlr
*org.hibernate.hql.ast
*org.hibernate.hql.ast.exec
*org.hibernate.hql.ast.tree
*org.hibernate.hql.ast.util
*org.hibernate.hql.classic
*org.hibernate.id
*org.hibernate.impl
*org.hibernate.intercept
*org.hibernate.jdbc
*org.hibernate.jmx
*org.hibernate.loader
*org.hibernate.loader.collection
*org.hibernate.loader.criteria
*org.hibernate.loader.custom
*org.hibernate.loader.entity
*org.hibernate.loader.hql
*org.hibernate.lob
*org.hibernate.mapping
*org.hibernate.metadata
*org.hibernate.param
*org.hibernate.persister
*org.hibernate.persister.collection
*org.hibernate.persister.entity
*org.hibernate.pretty
*org.hibernate.property
*org.hibernate.proxy
*org.hibernate.secure
*org.hibernate.sql
*org.hibernate.stat
*org.hibernate.tool.hbm2ddl
*org.hibernate.tool.instrument
*org.hibernate.transaction
*org.hibernate.transform
*org.hibernate.tuple
*org.hibernate.type
*org.hibernate.usertype
*org.hibernate.util
*org.objectweb.asm
*org.objectweb.asm.attrs
4 On Extensions, add the extension point, org.eclipse.datatools.connectivity.oda.dataSource, and the following elements and details for:
*dataSource
Add the extension element details, as shown in Table 20‑11.
Table 20‑11 Property settings for the Hibernate dataSource extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate
driverClass
org.eclipse.birt.report.data.oda.hibernate.HibernateDriver
odaVersion
3.2
defaultDisplayName
Hibernate Data Source
setThreadContextClassLoader
true
overrideExplorerFiltering
 
The dataSource extension has an attribute named setThreadContextClassLoader, which, if set to true, sets the thread context class loader to the Hibernate ODA plug-in class loader. In this example, this attribute is set to true to avoid potential class conflicts with classes loaded with the Eclipse Tomcat plug-in.
*dataSet
Add the extension element details, as shown in Table 20‑12.
Table 20‑12 Property settings for the Hibernate dataSet extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate.dataSet
defaultDisplayName
Hibernate Data Set
5 In Extensions, select dataSource and add the following properties and element details, setting all other details to blank:
*HIBCONFIG, as shown in Table 20‑13
Table 20‑13 HIBCONFIG property settings
Property
Value
name
HIBCONFIG
defaultDisplayName
Hibernate Configuration File
type
string
canInherit
true
*MAPDIR, as shown in Table 20‑14
Table 20‑14 MAPDIR property settings
Property
Value
name
MAPDIR
defaultDisplayName
Hibernate Mapping Directory
type
string
canInherit
true
6 In Extensions, select dataSet and add the list of dataTypeMapping elements, as shown in Table 20‑15.
Table 20‑15 Settings for Hibernate dataTypeMapping elements
nativeDataTypeCode
nativeDataType
odaScalarDataType
-5
BIGINT
Decimal
-2
BINARY
String
-7
BIT
Integer
2004
BLOB
Blob
16
BOOLEAN
Integer
1
CHAR
String
2005
CLOB
Clob
91
DATE
Date
3
DECIMAL
Decimal
8
DOUBLE
Double
6
FLOAT
Double
4
INTEGER
Integer
-4
LONGVARBINARY
String
-1
LONGVARCHAR
String
2
NUMERIC
Decimal
7
REAL
Double
5
SMALLINT
Integer
92
TIME
Time
93
TIMESTAMP
Timestamp
-6
TINYINT
Integer
-3
VARBINARY
String
12
VARCHAR
String
Understanding the sample Hibernate ODA driver extension
The package for the Hibernate ODA extension example, org.eclipse.birt.report.data.oda.hibernate, implements the following classes using the ODA plug-in interfaces defined in the DTP plug-in, org.eclipse.datatools.connectivity.oda, and the extension points defined in the XML schema file, datasource.exsd. The package implements the following classes:
*Activator
Extends org.eclipse.core.runtime.Plugin. Defines the methods for starting, managing, and stopping a plug-in instance.
*HibernateDriver
Implements the IDriver interface. Instantiates the connection object for the Hibernate ODA driver, which provides the entry point for the Hibernate ODA plug‑in.
*Connection
Implements the IConnection interface. Opens and closes the connection to the Hibernate ODA data source and instantiates the IQuery object.
*Statement
Implements the IQuery interface. Prepares the result set metadata containing the table and column names, executes the query, and fetches the data rows from the data source. This class is used instead of the default Query class added by the plug-in wizard to avoid name conflicts with org.hibernate.Query.
*ResultSet
Implements the IResultSet interface. Provides access to the data rows in the result set, maintaining a cursor that points to the current row. Handles the processing that gets the value for a column as the specified data type.
*ResultSetMetaData
Implements the IResultSetMetaData interface. Describes the metadata for each column in the result set.
*DataSetMetaData
Implements the IDataSetMetaData interface. Describes the features and capabilities of the driver for the data set.
*Messages
Defines the exception messages for the Hibernate ODA driver.
*DataTypes
Defines, validates, and returns the data types supported by the Hibernate ODA driver.
*CommonConstant
Defines the constants used in the package, such as the driver name, ODA version, query keywords, and delimiters.
*HibernateUtil
Manages the Hibernate SessionFactory that provides the session or run‑time interface between the Hibernate service and the ODA driver. This class is built based on the example HibernateUtil, available at http://www.hibernate.org.
The Hibernate ODA driver plug-in supports specifying the Hibernate configuration file and mapping files directory in the data source wizard. The plug-in creates the Hibernate SessionFactory from these settings. The example project has an exampleconfig directory that contains a Hibernate configuration and mapping files for use with the BIRT MySQL example database, Classic Models, Inc.
The following sections describe the classes where there are important differences between the implementation of Hibernate ODA driver and the earlier example, the CSV ODA driver.
Understanding HibernateDriver
The HibernateDriver class instantiates the Connection object for the Hibernate ODA driver. This class implements the IDriver interface, but does not provide any processing for the methods that configure logging and set the application context. Listing 20‑33 shows the getConnection( ) method.
Listing 20‑33 The getConnection( ) method
public IConnection getConnection( String connectionClassName )
throws OdaException
{
return new Connection( );
}
getMaxConnections( ) returns 0, imposing no limit on the number of connections to the ODA data source from the application. Listing 20‑34 shows the getMaxConnections( ) method.
Listing 20‑34 The getMaxConnections( ) method
public int getMaxConnections( ) throws OdaException
{
return( 0 );
}
Understanding Connection
The Connection class implements the following methods:
*open( )
Opens a Hibernate session and sets the Boolean variable, isOpen, to true. The open( ) method uses the HibernateUtil class to obtain a session from a Hibernate SessionFactory, providing the run-time interface between the Hibernate service and the ODA driver.
The open( ) method retrieves the locations for the Hibernate configuration file and mapping files directory from connection properties. The open( ) method calls HibernateUtil.constructSessionFactory( ), which attempts to build the SessionFactory with these settings. If the SessionFactory already exists, the plug-in does not recreate the SessionFactory unless the Hibernate configuration file or the mapping directory have changed.
Listing 20‑35 shows the code for the open( ) method.
Listing 20‑35 The open( ) method
public void open( Properties connProperties )
throws OdaException
{
try
{
configfile =
connProperties.getProperty( "HIBCONFIG" );
mapdir = connProperties.getProperty( "MAPDIR" );
HibernateUtil
.constructSessionFactory( configfile, mapdir );
Session testSession = HibernateUtil.currentSession( );
this.isOpen = true;
}catch( Exception e )
{
throw new OdaException( e.getLocalizedMessage( ) );
}
}
*newQuery( )
Opens a new query by returning an instance of a Statement object, the class that implements the IQuery interface. The connection can handle multiple result set types, but the Hibernate ODA example uses only one and ignores the dataSetType parameter, as shown in Listing 20‑36.
Listing 20‑36 The newQuery( ) method
public IQuery newQuery( String dataSetType )
throws OdaException
{
if ( !isOpen( ) )
throw new OdaException( Messages.getString
( "Common.CONNECTION_IS_NOT_OPEN" ) );
return new Statement( this );
}
*getMetaData( )
Returns an IDataSetMetaData object of the data set type, as shown in Listing 20‑37.
Listing 20‑37 The getMetaData( ) method
public IDataSetMetaData getMetaData( String dataSetType )
throws OdaException
{
return new DataSetMetaData( this );
}
*getMaxQueries( )
Indicates the maximum number of queries the driver supports. The getMaxQueries( ) method returns 1, indicating that the Hibernate ODA driver does not support concurrent queries, as shown in Listing 20‑38.
Listing 20‑38 The getMaxQueries( ) method
public int getMaxQueries( ) throws OdaException
{
return 1;
}
*commit( ) and rollback( )
Handle transaction processing. The Hibernate ODA driver example does not support transaction operations. In the Connection class, the commit( ) and rollback( ) methods throw UnsupportedOperationException. Listing 20‑39 shows the code for the commit( ) method.
Listing 20‑39 The commit( ) method
public void commit( ) throws OdaException
{
throw new UnsupportedOperationException ( );
}
*close( )
Closes the Hibernate session, as shown in Listing 20‑40.
Listing 20‑40 The close( ) method
public void close( ) throws OdaException
{
this.isOpen = false;
try{
HibernateUtil.closeSession( );
}catch(Exception e){
throw new OdaException( e.getLocalizedMessage( ) );
}
}
Understanding DataSetMetaData
The DataSetMetaData class describes the features and capabilities of the data source for the specified data set. The Hibernate ODA driver example returns true or false to indicate support for a feature. The Hibernate ODA driver example does not support input or output parameters, named parameters, or multiple result sets.
The following code example indicates that the Hibernate ODA driver does not support multiple result sets, as shown in Listing 20‑41.
Listing 20‑41 The supportsMultipleResultSets( ) method
public boolean supportsMultipleResultSets( ) throws OdaException
{
return false;
}
A method such as getSQLStateType( ), which has no implementation, simply throws UnsupportedOperationException, as shown in Listing 20‑42.
Listing 20‑42 The getSQLStateType( ) method
public int getSQLStateType( ) throws OdaException
{
throw new UnsupportedOperationException ( );
}
Understanding Statement
The Statement class implements the IQuery interface. This class prepares and executes the query. Statement also handles parameters and retrieves the result set and result set metadata.
The Statement class implements the following methods:
*prepare( )
The ODA framework calls the prepare( ) method before executing the query. The ODA framework uses the query saved in the report design.
The Hibernate ODA user interface plug-in also calls prepare( ) to verify the columns used in the report design. The user interface plug-in passes an HQL statement that gets the columns from the result set object.
prepare( ) sets up the result-set metadata and stores the query in an object variable for use by the executeQuery( ) method. The ODA run time uses the result-set metadata to retrieve the data. BIRT Report Designer also uses the result-set metadata to display the columns in the user interface.
The prepare( ) method performs the following operations:
*Sets up array lists to contain the columns, column types, and column classes
*Trims the query String
*Creates a Hibernate Query object, using the HQL query
*Gets the Hibernate column names, types, and classes for the query
*Instantiates a ResultSetMetaData object, passing in the column names and data types
*Saves the query for execution
Listing 20‑43 shows the code for the prepare( ) method.
Listing 20‑43 The prepare( ) method
public void prepare( String query ) throws OdaException
{
Query qry = null;
testConnection( );
ArrayList arColsType = new ArrayList( );
ArrayList arCols = new ArrayList( );
ArrayList arColClass = new ArrayList( );
String[ ] props = null;
try
{
Session hibsession = HibernateUtil.currentSession( );
query = query.replaceAll( "[\\n\\r]+"," " );
query = query.trim( );
qry = hibsession.createQuery( query );
Type[ ] qryReturnTypes = qry.getReturnTypes( );
if( qryReturnTypes.length > 0
&& qryReturnTypes[0].isEntityType( ) )
{
for( int j=0; j< qryReturnTypes.length; j++ )
{
String clsName=qryReturnTypes[j].getName( );
props =
HibernateUtil.getHibernateProp( clsName );
for( int x = 0; x < props.length; x++ )
{
String propType =
HibernateUtil.getHibernatePropTypes
( clsName, props[x] );
if( DataTypes.isValidType( propType ))
{
arColsType.add( propType );
arCols.add( props[x] );
arColClass.add( clsName );
}
else
{
throw new OdaException
( Messages.getString
( "Statement.SOURCE_DATA_ERROR" ) );
}
}
}
}
else
{
props = extractColumns( qry.getQueryString( ) );
for( int t=0; t < qryReturnTypes.length; t++)
{
if( DataTypes.isValidType
(qryReturnTypes[t].getName( )))
{
arColsType.add( qryReturnTypes[t].getName( ));
arCols.add( props[t] );
}
else
{
throw new OdaException
( Messages.getString
("Statement.SOURCE_DATA_ERROR") );
}
}
}
}
catch( Exception e )
{
throw new OdaException( e.getLocalizedMessage( ) );
}
this.resultSetMetaData = new ResultSetMetaData
(( String[ ])arCols.toArray
( new String[arCols.size( )] ),
(String[ ])arColsType.toArray
( new String[arColsType.size( )] ),
(String[ ])arCols.toArray
( new String[arCols.size( )] ),
(String[ ])arColClass.toArray
( new String[arColClass.size( )] ));
this.query = query;
}
*getMetaData( )
The BIRT framework calls getMetaData( ) after the prepare( ) method to retrieve the metadata for a result set. The BIRT framework uses the metadata to create the data set in the report.
Listing 20‑44 shows the code for the getMetaData( ) method.
Listing 20‑44 The getMetaData( ) method
public IResultSetMetaData getMetaData( ) throws OdaException
{
return this.resultSetMetaData;
}
*executeQuery( )
The executeQuery( ) method executes the prepared query and retrieves the results. The executeQuery( ) method returns an IResultSet object, which is created using the list results, result-set metadata, and Hibernate types returned from the HQL query. The ODA framework uses the IResultSet object to iterate over the results.
The executeQuery( ) method performs the following operations:
*Sets up an array of org.hibernate.type.Type to map Java types to JDBC data types
*Sets up a list to contain the results set
*Trims the query String
*Instantiates a Hibernate Query object, creating the HQL query
*Executes the HQL query, returning the query result set in a List
*Gets the Hibernate types for the query result set
*Instantiates a ResultSet object, passing in the data, metadata, and Hibernate types
Listing 20‑45 shows the code for the executeQuery( ) method.
Listing 20‑45 The executeQuery( ) method
public IResultSet executeQuery( ) throws OdaException
{
Type[ ] qryReturnTypes = null;
List rst = null;
try
{
Session hibsession = HibernateUtil.currentSession( );
String qryStr = this.query;
qryStr = qryStr.replaceAll( "[\\n\\r]+"," " );
qryStr.trim( );
Query qry = hibsession.createQuery( qryStr );
rst = qry.list( );
qryReturnTypes = qry.getReturnTypes( );
}
catch( Exception e )
{
throw new OdaException( e.getLocalizedMessage( ) );
}
return new ResultSet
( rst, getMetaData( ), qryReturnTypes );
}
*close( )
The close( ) method clears the Connection and ResultSetMetaData objects. In the Connection object, the close( ) method closes the Hibernate session.
Listing 20‑46 shows the code for the Statement.close( ) method.
Listing 20‑46 The Statement.close( ) method
public void close( ) throws OdaException
{
connection = null;
resultSetMetaData = null;
mmaxRows = 0;
}
Understanding ResultSet
The ResultSet class implements the IResultSet interface. When this class is instantiated, it stores the list.iterator( ) passed from the Statement object. It uses the iterator when the ODA driver framework calls the next( ) method.
The iterator points to the next available row of data from the HQL query results. The framework calls the accessor methods that get the data types for the columns in the current row. For example, if the first column is a String, the framework calls getString( ). This method calls the getResult( ) method, which interprets the HQL query results.
The getResult( ) method parses the results in one of the following ways, depending on whether the query returns a Hibernate EntityType or just an array of values:
*If the query uses HQL and each return type is an EntityType, getResult( ) gets each Column class and uses the Hibernate ClassMetaData methods to retrieve the value.
*If the query returns standard data types, getResult( ) gets each value or values, returning an Object containing the simple value or an array of Objects containing the multiple values.
Listing 20‑47 shows the code for the getResult( ) method.
Listing 20‑47 The getResult( ) method
private Object getResult( int rstcol ) throws OdaException
{
Object obj = this.currentRow;
Object value = null;
 
try
{
 
if( qryReturnTypes.length >
0 && qryReturnTypes[0].isEntityType( ))
{
String checkClass =
(( ResultSetMetaData )getMetaData( ))
.getColumnClass(rstcol);
Object myVal =
HibernateUtil.getHibernatePropVal( obj,
checkClass,
getMetaData( ).getColumnName( rstcol ));
value = myVal;
}
else
{
if( getMetaData( ).getColumnCount( ) == 1)
{
value = obj;
}
else
{
Object[ ] values = ( Object[ ])obj;
value = values[rstcol-1];
}
 
}
}
catch( Exception e )
{
throw new OdaException( e.getLocalizedMessage( ) );
}
 
return( value );
}
Understanding HibernateUtil
HibernateUtil is a utility class that provides the run-time interface between the Hibernate service and the application. The HibernateUtil class example derives from the class provided with the Hibernate documentation. HibernateUtil performs the following operations:
*Initializes the SessionFactory
*Builds the Hibernate SessionFactory
*Opens and closes a session
*Returns information on Hibernate classes and properties
*Registers the JDBC driver with the DriverManager
Connection.open( ) calls HiberFnateUtil.constructSessionFactory( ), which creates a SessionFactory if one does not already exist. The constructSessionFactory( ) method closes and rebuilds the SessionFactory if the location of the configuration file or mapping files directory has changed.
The SessionFactory construction process creates the ClassLoader. The ClassLoader adds the drivers directory in the org.eclipse.birt.report.data.oda.jdbc plug-in and the hibfiles directory in the Hibernate ODA plug-in to classpath. This process also registers the JDBC driver specified in the Hibernate config file with the DriverManager.
The HibernateUtil class implements the following methods:
*initSessionFactory( )
This method creates the SessionFactory object from the configuration settings in the hibernate.cfg.xml file.
Listing 20‑48 shows the code for the initSessionFactory( ) method.
Listing 20‑48 The initSessionFactory( ) method
private static synchronized void initSessionFactory
( String hibfile, String mapdir ) throws HibernateException
{
 
if( sessionFactory == null)
{
Thread thread = Thread.currentThread( );
 
try
{
oldloader = thread.getContextClassLoader( );
refreshURLs( );
ClassLoader changeLoader = new URLClassLoader
( ( URL [ ])URLList.toArray
( new URL[0]),thread
.getContextClassLoader( ));
thread.setContextClassLoader( changeLoader );
Configuration cfg =
buildConfig( hibfile,mapdir );
Class driverClass =
changeLoader.loadClass( cfg.getProperty
( "connection.driver_class" ));
Driver driver =
( Driver ) driverClass.newInstance( );
WrappedDriver wd =
new WrappedDriver( driver,
cfg.getProperty
( "connection.driver_class" ));
boolean foundDriver = false;
Enumeration drivers =
DriverManager.getDrivers( );
while ( drivers.hasMoreElements( ))
{
Driver nextDriver =
( Driver )drivers.nextElement( );
if ( nextDriver.getClass( ) == wd.getClass( ))
{
if( nextDriver.toString( )
.equals(wd.toString( )) )
{
foundDriver = true;
break;
}
}
}
 
if( !foundDriver )
{
DriverManager.registerDriver( wd );
}
sessionFactory = cfg.buildSessionFactory( );
configuration = cfg;
HibernateMapDirectory = mapdir;
HibernateConfigFile = hibfile;
}
catch( Exception e)
{
e.printStackTrace( );
throw new HibernateException
( "No Session Factory Created " +
e.getLocalizedMessage( ));
}
finally
{
thread.setContextClassLoader( oldloader );
}
}
}
*constructSessionFactory
This method checks to see if a configuration change occurred. If a change occurred, the method closes the session and SessionFactory and calls the initSessionFactory to rebuild the SessionFactory.
Listing 20‑49 shows the code for the constructSessionFactory( ) method.
Listing 20‑49 The constructSessionFactory( ) method
public static void constructSessionFactory( String hibfile, String mapdir ) throws HibernateException
{
if( hibfile == null)
{
hibfile = "";
}
if( mapdir == null)
{
mapdir = "";
}
if( sessionFactory == null)
{
initSessionFactory( hibfile, mapdir);
return;
}
if( HibernateMapDirectory.equalsIgnoreCase
( mapdir ) && HibernateConfigFile
.equalsIgnoreCase( hibfile ))
{
return;
}
synchronized( sessionFactory )
{
Session s = ( Session ) session.get( );
if ( s != null )
{
closeSession( );
}
if ( sessionFactory != null &&
!sessionFactory.isClosed( ))
{
closeFactory( );
}
sessionFactory = null;
initSessionFactory( hibfile, mapdir);
}
*currentSession( )
This method opens a session when called by the Connection.open( ) method, as shown in Listing 20‑50.
Listing 20‑50 The currentSession( ) method
public static Session currentSession( )
throws HibernateException {
Session s = ( Session ) session.get( );
if ( s == null ) {
s = sessionFactory.openSession( );
session.set( s );
}
return s;
}
Other methods in this class return information on a particular class and its properties. The getHibernateProp( ) method returns the properties for a class. The getHibernatePropTypes( ) method returns the data type for a property of a class.
Building the Hibernate ODA driver plug-in
To build and deploy the org.eclipse.birt.report.data.oda.hibernate plug-in using the Eclipse PDE Manifest Editor, perform the following tasks:
*In Build, specify the build configuration to include the following items:
*In Runtime Information, add the odahibernate.jar file.
*In BuildBinary Build, select the following files and folders:
*META-INF
*exampleconfig
*hibfiles
*lib
*plugin.xml
*In Overview, in Exporting, choose Export Wizard and perform the following tasks:
*In Available Plug-ins and Fragments, select org.eclipse.birt.report.data.oda.hibernate.
*In Options, verify that Package plug-ins as individual JAR archives is not selected.
In Destination, choose the directory, \birt-runtime-4_3_1\Report Engine. The Hibernate ODA example uses MySQL as the database. The BIRT sample database and the MySQL installation scripts can be downloaded fromhttp://www.eclipse.org/birt/db. For information about the required Hibernate libraries, please refer to the Hibernate website at http://www.hibernate.org.
Developing the Hibernate ODA user interface extension
To use the data retrieved by the Hibernate ODA driver in a BIRT report design, you must extend the DTP design user interface. To implement the Hibernate ODA user interface, you extend the following extension points:
*org.eclipse.datatools.connectivity.oda.design.ui.dataSource
The dataSource extension point defines and implements the user interface for new data source and data set wizards. These wizards use the Hibernate ODA driver plug-in to extend the functionality available in the Data Explorer of BIRT Report Designer.
*org.eclipse.ui.propertyPages
The propertyPages extension displays and manipulates the Hibernate configuration file and mapping files directory locations.
*org.eclipse.datatools.connectivity.connectionProfile
The connectionProfile extension shares a data source connection between applications.
To start developing the Hibernate ODA user interface plug-in, create the plug-in project, org.eclipse.birt.report.data.oda.hibernate.ui.
How to create the Hibernate ODA user interface plug-in project
1 From the Eclipse menu, choose FileNewProject.
2 On New Project—Select a wizard, open Business Intelligence and Reporting Tools and select ODA Designer Plug-in Project. Choose Next.
3 In Plug-in Project, modify the settings as shown in Table 20‑16. Choose Next.
Table 20‑16 Settings for the Hibernate ODA UI plug-in project options
Section
Option
Value
Plug-in Project
Project name
org.eclipse.birt.report.data.oda.hibernate.ui
 
Use default location
Selected
 
Location
Not available when you select Use default location
Project Setting
Create a Java project
Selected
 
Source folder name
src
 
Output folder name
bin
Target Platform
Eclipse version
3.5 or greater
 
OSGi framework
Deselected
Working Sets
Add project to working sets
Not selected
4 In Plug-in Content, modify the settings as shown in Table 20‑17. Choose Finish.
Table 20‑17 Settings for the Hibernate ODA UI plug-in content options
Section
Option
Value
Properties
ID
org.eclipse.birt.report.data.oda.hibernate.ui
 
Version
2.0.0
 
Name
BIRT Hibernate User Interface Plug-in
 
Vendor
yourCompany.com or leave blank
 
Execution Environment
JavaSE-1.6
Options
Generate an activator, a Java class that controls the plug‑in’s life cycle
Selected
 
Activator
org.eclipse.birt.report.data.oda.hibernate.ui.Activator
 
This plug-in will make contributions to the user interface
Selected
 
Enable API Analysis
Deselected
Rich Client Application
Would you like to create a 3.x rich client application?
No
5 In Templates, choose ODA Data Source Designer. Choose Next.
6 In ODA Data Source Designer, specify new values for the following options used to generate the Hibernate ODA user interface plug-in, as shown in Table 20‑18. Choose Finish.
Table 20‑18 Settings for the Hibernate ODA data source designer options
Option
Value
Java Package Name
org.eclipse.birt.report.data.oda.hibernate.ui
ODA Runtime Driver Plug-in Id
org.eclipse.birt.report.data.oda.hibernate
ODA Runtime Data Source Element Id
org.eclipse.birt.report.data.oda.hibernate
ODA Runtime Driver Class
org.eclipse.birt.report.data.oda.hibernate.Driver
ODA Runtime Data Set Element Id
org.eclipse.birt.report.data.oda.hibernate.dataSet
Data Source Display Name
ODA Hibernate File Designer Data Source
Data Set Display Name
ODA Hibernate File Designer Data Set
The Hibernate ODA user interface plug-in project appears in the Eclipse PDE Workbench.
How to specify the Hibernate ODA user interface dependencies
On the Eclipse PDE Manifest Editor, in Dependencies, specify the required plug-ins in the following order:
*org.eclipse.core.runtime
*org.eclipse.ui
*org.eclipse.datatools.connectivity.oda.design.ui
*org.eclipse.birt.report.data.oda.hibernate
How to specify the Hibernate ODA user interface run time
On Runtime, in Exported Packages, add org.eclipse.birt.report.oda.hibernate.ui to the list of packages that this plug-in exposes to clients.
How to specify the Hibernate ODA user interface extensions
1 Check to ensure that the following extensions have been defined:
*org.eclipse.datatools.connectivity.oda.design.ui.dataSource
*org.eclipse.ui.propertyPages
*org.eclipse.datatools.connectivity.connectionProfile
2 In Extensions, select the extension point, org.eclipse.datatools.connectivity.oda.design.ui.dataSource, and add the following elements and element details:
*dataSourceUI
Add the extension element details for the newDataSourceWizard extension element, as shown in Table 20‑19.
Table 20‑19 Property settings for the Hibernate newDataSourceWizard extension element
Property
Value
pageClass
org.eclipse.birt.report.data.oda.hibernate.ui.HibernateDataSourceWizard
windowTitle
Hibernate Data Source
includesProgressMonitor
false
pageTitle
Hibernate Data Source
*dataSetUI
Add the extension element details for the extension element, dataSetUI, as shown in Table 20‑20.
Table 20‑20 Property settings for the Hibernate dataSetUI extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate.dataSet
initialPageId
org.eclipse.birt.report.data.oda.hibernate.ui.HibernatePage
supportsInParameters
true
supportsOutParameters
false
3 In Extensions, select dataSetUI, and add the following properties and element details:
*dataSetWizard, as shown in Table 20‑21
Table 20‑21 Property settings for the Hibernate dataSetWizard extension element
Property
Value
class
org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizard
windowTitle
Hibernate Data Set
*dataSetPage, as shown in Table 20‑22
Table 20‑22 Property settings for the Hibernate dataSetPage extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate.ui.HibernatePage
wizardPageClass
org.eclipse.birt.report.data.oda.hibernate.ui.HibernateHqlSelectionPage
displayName
Enter HQL
path
/
4 In Extensions, select org.eclipse.ui.propertyPages, and add the following ODA Hibernate Data Source Connection Properties (page) property and extension element details, as shown in Table 20‑23.
Table 20‑23 Property settings for the Hibernate page extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate
name
ODA Hibernate Data Source Connection Properties
class
org.eclipse.birt.report.data.oda.hibernate.ui.HibernatePropertyPage
objectClass
org.eclipse.datatools.connectivity.IConnectionProfile
5 In Extensions, select page, and add the following filter property and extension element details, as shown in Table 20‑24.
Table 20‑24 Property settings for the Hibernate filter extension element
Property
Value
name
org.eclipse.datatools.profile.property.id
value
org.eclipse.birt.report.data.oda.hibernate
6 In Extensions, select org.eclipse.datatools.connectivity.connectionProfile, and add the following properties and element details:
*category, as shown in Table 20‑25
Table 20‑25 Property settings for the Hibernate category extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate
parentCategory
org.eclipse.datatools.connectivity.oda.profileCategory
name
Hibernate Data Source
*connectionProfile, as shown in Table 20‑26
Table 20‑26 Property settings for the Hibernate connectionProfile extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate
category
org.eclipse.birt.report.data.oda.hibernate
name
ODA Hibernate Data Source Connection Profile
pingFactory
org.eclipse.datatoools.connectivity.oda.profile.OdaConnectionFactory
*connectionFactory, as shown in Table 20‑27
Table 20‑27 Property settings for the Hibernate connectionFactory extension element
Property
Value
id
org.eclipse.datatools.connectivity.oda.IConnection
class
org.eclipse.datatools.connectivity.oda.profile.OdaConnectionFactory
profile
org.eclipse.birt.report.data.oda.hibernate
name
ODA Connection Factory
*newWizard, as shown in Table 20‑28
Table 20‑28 Property settings for the Hibernate newWizard extension element
Property
Value
id
org.eclipse.birt.report.data.oda.hibernate
name
ODA Hibernate Data Source
class
org.eclipse.datatools.connectivity.oda.design.ui.wizards.NewDataSourceWizard
profile
org.eclipse.birt.report.data.oda.hibernate
description
Create an ODA Hibernate connection profile
The completed extension definitions appear as shown in Figure 20‑22.
Figure 20‑22 Extensions for the Hibernate ODA UI