The sample Hibernate ODA UI extension
The following sections describe the code-based extensions a developer must make to complete the development of the Hibernate ODA user interface extension, after defining the plug-in framework in the Eclipse PDE.
The Hibernate ODA user interface plug-in implements the following classes:
*HibernatePropertyPage
Creates and initializes the editor controls for the property page that specify the ODA data source. This class updates the connection profile properties with the values collected from the page. HibernatePropertyPage extends org.eclipse
.datatools.connectivity.oda.design.ui.wizards.DataSourceEditorPage, the abstract base class for implementing a customized ODA data source property page.
*HibernatePageHelper
Implements the user interface that specifies data source properties. This utility class specifies the page layout, sets up the controls that listen for user input, verifies the location of the Hibernate configuration file, and sets up the location of the mapping directory. The HibernateDataSourceWizard and HibernatePropertyPage classes use HibernatePageHelper.
*HibernateDataSourceWizard
Creates and initializes the controls for the data source wizard page. The
class sets the configuration file message and collects the property values. In the extension element settings for newDataSourceWizard, the pageClass property specifies this class as the implementation class for the dataSourceUI wizard. The HibernateDataSourceWizard class extends org.eclipse.datatools
.connectivity.oda.design.ui.wizards.DataSourceWizardPage, the abstract base class for implementing a customized ODA data source wizard page.
*HibernateHqlSelectionPage
Creates the user interface that specifies an HQL statement. The Hibernate ODA user interface plug-in calls HibernateHqlSelectionPage when creating
or modifying the data set for a data source. In the extension element
settings for dataSetPage, the wizardPageClass property specifies this class
as the implementation class for the dataSetUI page wizard. HibernateHqlSelectionPage also extends org.eclipse.datatools
.connectivity.oda.design.ui.wizards.DataSourceWizardPage.
*Messages
This class and the related properties file, messages.properties, generate the messages displayed in the Hibernate ODA user interface.
HibernatePageHelper class
This class creates the components that select the Hibernate configuration file and a mapping files directory using the following methods:
*createCustomControl( )
Builds the user interface for the data source
*initCustomControl( )
Sets the initial property values
*collectCustomProperties( )
Returns the modified properties to the ODA framework
When the data source page displays, the Finish button becomes available when the setPageComplete( ) method indicates the page is complete.
HibernateDataSourceWizard.createPageCustomControl( ) and HibernatePropertyPage.createAndInitCustomControl( ) call HibernatePageHelper. The createCustomControl( ) method is the entry
point for this class.
Listing 25‑51 shows the code for the createCustomControl( ) method.
Listing 25‑51 The createCustomControl( ) method
void createCustomControl( Composite parent )
{
Composite content = new Composite( parent, SWT.NULL );
GridLayout layout = new GridLayout( 3, false );
content.setLayout(layout);
setupConfigLocation( content );
setupMapLocation( content );
The setupConfigLocation( ) method sets up the configuration file location. The setupMapLocation( ) method sets up the mapping folder. These two methods perform similar tasks.
Listing 25‑52 shows the code for the setupConfigLocation( ) method. This method adds a label, a text entry component, and a button. The text entry component has a ModifyListener( ) method, which verifies that the file selected exists, and the button has a SelectionAdapter( ) method, which uses the FileDialog( ) method to access the configuration file.
Listing 25‑52 The setupConfigLocation( ) method
private void setupConfigLocation( Composite composite )
{
Label label = new Label( composite, SWT.NONE );
label.setText("Select Hibernate Config File" );
GridData data = new GridData( GridData.FILL_HORIZONTAL );
m_configLocation = new Text( composite, SWT.BORDER );
m_configLocation.setLayoutData( data );
setPageComplete( true );
m_configLocation.addModifyListener( new ModifyListener( )
{
public void modifyText( ModifyEvent e )
{
verifyConfigLocation( );
}
);
m_browseConfigButton = new Button( composite, SWT.NONE );
m_browseConfigButton.setText( "..." );
m_browseConfigButton.addSelectionListener(
new SelectionAdapter( )
{
public void widgetSelected( SelectionEvent e )
{
FileDialog dialog = new FileDialog(
m_configLocation.getShell( ) );
if ( m_configLocation.getText( ) != null
&& m_configLocation.getText( ).trim( ).length( ) > 0 )
{
dialog.setFilterPath( m_configLocation.getText() );
}
dialog.setText( "Select Hibernate Config File" );
String selectedLocation = dialog.open( );
if( selectedLocation != null )
{
m_configLocation.setText( selectedLocation );
}
}
} );
}
The initCustomControl( ) method initializes the properties settings. The plug-in passes the properties to the method from the createPageCustomControl( ) and setInitialProperties( ) methods of the HibernateDataSourceWizard class and the createAndInitCustomControl( ) method of the HibernatePropertyPage class.
The initCustomControl( ) method retrieves the properties for the Hibernate configuration file and mapping files directory and sets text component values.
Listing 25‑53 shows the code for the initCustomControl( ) method.
Listing 25‑53 The initCustomControl( ) method
void initCustomControl( Properties profileProps )
{
setPageComplete( true );
setMessage( DEFAULT_MESSAGE, IMessageProvider.NONE );
if ( profileProps == null || profileProps.isEmpty()
|| m_configLocation == null )
{
return;
}
String configPath = profileProps.getProperty( "HIBCONFIG" );
if ( configPath == null )
{
configPath = EMPTY_STRING;
}
m_configLocation.setText( configPath );
String mapPath = profileProps.getProperty( "MAPDIR" );
if ( mapPath == null )
{
mapPath = EMPTY_STRING;
}
m_mapLocation.setText( mapPath );
verifyConfigLocation( );
}
When the user presses the Finish or Test Connection button, the plug-in
calls the collectCustomProperties( ) method to retrieve the new values for
the Hibernate configuration file and mapping files directory. The HibernateDataSourceWizard and HibernatePropertyPage classes call the HibernatePageHelper.collectCustomProperties( ) method from their collectCustomProperties( ) methods.
Listing 25‑54 shows the code for the collectCustomProperties( ) method.
Listing 25‑54 The collectCustomProperties( ) method
Properties collectCustomProperties( Properties props )
{
if( props == null )
{
props = new Properties( );
}
props.setProperty( "HIBCONFIG", getConfig( ) );
props.setProperty( "MAPDIR", getMapDir( ) );
return props;
}
HibernateDataSourceWizard class
The HibernateDataSourceWizard class extends the DTP DataSourceWizardPage by implementing three methods that the ODA framework calls:
*createPageCustomControl( )
Constructs the user interface
*setInitialProperties( )
Sets the initial values of the user interface
*collectCustomProperties( )
Retrieve the modified values
This class creates the HibernatePageHelper class, and uses the methods described earlier to handle these three methods. The ODA framework uses this class to create a new data source.
HibernatePropertyPage class
The HibernatePropertyPage class extends the DTP DataSourceEditorPage by implementing two methods that the ODA framework calls:
*createAndInitCustomControl( )
Constructs the user interface and sets the initial values
*collectCustomProperties( )
Retrieves the modified values
This class creates the HibernatePageHelper class and uses the methods described earlier to handle these two methods. The ODA framework uses this class to create a new data source.
HibernateHqlSelectionPage class
The HibernateHqlSelectionPage class extends DataSetWizardPage to define the page controls and related functionality for the Hibernate ODA data set wizard. HibernateHqlSelectionPage allows the user to create an HQL statement that selects the data set and embeds the HQL statement in the report design. This page links to the Hibernate ODA through the wizardPageClass attribute of the dataSetPage element within the dataSource extension.
The HibernateHqlSelectionPage class implements the following methods:
*createPageControl( )
This method performs the following operations:
*Sets up a composite set of controls using a series of GridLayout and GridData objects to create the data set editor user interface
*Sets the user prompt to enter an HQL statement and verify the query
*Adds a text control to allow the user to enter and modify text
*Adds a ModifyListener to the text control to detect user input
*Sets up the Verify Query button and adds a SelectionListener to detect when the user selects the button
*Returns the composite page control
Listing 25‑55 shows the code for the createPageControl( ) method.
Listing 25‑55 The createPageControl( ) method
public Control createPageControl( Composite parent )
{
Composite composite = new Composite( parent, SWT.NONE );
GridLayout layout = new GridLayout( );
layout.numColumns = 1;
composite.setLayout( layout );
Label label = new Label( composite, SWT.NONE );
label.setText( Messages.getString(
"wizard.title.selectColumns" ));
GridData data = new GridData( GridData.FILL_BOTH );
queryText = new Text( composite,SWT.MULTI | SWT.WRAP
| SWT.V_SCROLL );
queryText.setLayoutData( data );
 
queryText.addModifyListener( new ModifyListener( )
{
public void modifyText( ModifyEvent e )
{
if( m_initialized == false)
{
setPageComplete(true);
m_initialized = true;
}
else
{
setPageComplete(false);
}
}
} );
 
setPageComplete( false );
Composite cBottom = new Composite( composite, SWT.NONE );
cBottom.setLayoutData(
new GridData( GridData.FILL_HORIZONTAL ) );
cBottom.setLayout( new RowLayout( ) );
queryButton = new Button( cBottom, SWT.NONE );
queryButton.setText( Messages.getString(
"wizard.title.verify" ));
 
queryButton.addSelectionListener( new SelectionAdapter( )
{
public void widgetSelected( SelectionEvent event )
{
verifyQuery( );
}
} );
return composite;
}
*initializeControl( )
The plug-in calls this method to retrieve the HQL query from the current design and initializes the HQL text component with this value. initializeControl( ) also reads the Hibernate configuration file and mapping files directory from the report design and stores them in member variables for use when building a query.
Listing 25‑56 shows the code for the initializeControl( ) method.
Listing 25‑56 The initializeControl( ) method
private void initializeControl( )
{
Properties dataSourceProps = getInitializationDesign( )
.getDataSourceDesign( ).getPublicProperties( );
 
m_hibconfig = dataSourceProps.getProperty( "HIBCONFIG" );
m_mapdir = dataSourceProps.getProperty( "MAPDIR" );
 
DataSetDesign dataSetDesign = getInitializationDesign( );
if ( dataSetDesign == null )
{
return;
}
 
String queryTextTmp = dataSetDesign.getQueryText( );
if ( queryTextTmp == null )
{
return;
}
 
queryText.setText( queryTextTmp );
this.m_initialized = false;
setMessage( "", NONE );
}
*verifyQuery( )
This method is the selection event called when the user chooses the Verify Query button. verifyQuery performs the following operations:
*Opens a connection to the run-time environment.
*Instantiates a Query object and gets the query text entered by the user.
*Prepares the query.
*Checks the column to determine if the query prepare was successful. Depending on the success of the query prepare, verifyQuery( ) indicates that page processing is complete or incomplete.
*Re‑enables the Verify Query button.
*Closes the connection.
Listing 25‑57 shows the code for the verifyQuery( ) method.
Listing 25‑57 The verifyQuery( ) method
boolean verifyQuery( )
{
setMessage( "Verifying Query", INFORMATION );
setPageComplete( false );
queryButton.setEnabled( false );
Connection conn = new Connection( );
 
try {
Properties prop = new Properties( );
if ( m_hibconfig == null)
{
m_hibconfig = "";
}
if ( m_mapdir == null)
{
m_mapdir = "";
}
 
prop.put("HIBCONFIG", m_hibconfig );
prop.put("MAPDIR", m_mapdir);
conn.open( prop );
IQuery query = conn.newQuery( "" );
query.prepare( queryText.getText( ) );
int columnCount = query.getMetaData( ).getColumnCount( );
if ( columnCount == 0 )
{
setPageComplete( false );
return false;
}
setPageComplete( true );
return true;
}
 
catch ( OdaException e ) {
System.out.println( e.getMessage( ) );
setMessage( e.getLocalizedMessage( ), ERROR );
setPageComplete( false );
return false
}
 
catch ( Exception e ) {
System.out.println( e.getMessage( ) );
setMessage( e.getLocalizedMessage( ), ERROR );
setPageComplete( false );
return false;
}
 
finally {
try {
queryButton.setEnabled( true );
conn.close( );
}
catch ( OdaException e ) {
System.out.println( e.getMessage( ) );
setMessage( e.getLocalizedMessage( ), ERROR );
setPageComplete( false );
return false;
}
}
}
*savePage( )
The savePage( ) method is called when the ODA framework calls the collectDataSetDesign( ) method. This action occurs when the user presses the Finish button on the new data set wizard or the OK button on the data set editor is pressed. The savePage( ) method saves the query to the report, as shown in Listing 25‑58.
Listing 25‑58 The savePage( ) method
private boolean savePage( )
{
IConnection conn = null;
try {
IDriver hqDriver = new HibernateDriver( );
conn = hqDriver.getConnection( null );
IResultSetMetaData metadata = getResultSetMetaData(
dataSetDesign.getQueryText( ), conn );
setResultSetMetaData( dataSetDesign, metadata );
}
catch( OdaException e ) {
dataSetDesign.setResultSets( null );
}
finally {
closeConnection( conn );
}
}
*getResultSetMetaData( )
The savePage( ) method calls the getResultSetMetaData( ) method when saving the report design. This method retrieves the query metadata that setResultSetMetaData( ) uses to create the data set columns.
Listing 25‑59 shows the code for the getResultSetMetaData( ) method.
Listing 25‑59 The getResultSetMetaData( ) method
private IResultSetMetaData getResultSetMetaData(
String queryText, IConnection conn ) throws OdaException
{
java.util.Properties prop = new java.util.Properties( );
 
if ( m_hibconfig == null)
{
m_hibconfig = "";
}
if ( m_mapdir == null)
{
m_mapdir = "";
}
prop.put( "HIBCONFIG", m_hibconfig );
prop.put( "MAPDIR", m_mapdir );
conn.open( prop );
 
IQuery query = conn.newQuery( null );
query.prepare( queryText );
return query.getMetaData( );
}
*setResultSetMetaData( )
The savePage( ) method calls the setResultSetMetaData( ) method when saving the report design. This method uses the DataSetDesign and the ResultSetMetaData objects for the query to create the columns in the data set for use in the report design.
Listing 25‑60 shows the code for the setResultSetMetaData( ) method.
Listing 25‑60 The setResultSetMetaData( ) method
private void setResultSetMetaData( DataSetDesign dataSetDesign, IResultSetMetaData md ) throws OdaException
{
ResultSetColumns columns =
DesignSessionUtil.toResultSetColumnsDesign( md );
 
ResultSetDefinition resultSetDefn =
DesignFactory.eINSTANCE.createResultSetDefinition( );
 
resultSetDefn.setResultSetColumns( columns );
dataSetDesign.setPrimaryResultSet( resultSetDefn );
dataSetDesign.getResultSets().setDerivedMetaData( true );
}
*collectDataSetDesign( )
The plug-in calls this method when creating or modifying the query finishes. The plug-in passes the current design to this method. collectDataSetDesign( ) then verifies that a query exists and sets the design query to the value of the query text. The savePage( ) method saves the design and creates the columns in the data set.
Listing 25‑61 shows the code for the collectDataSetDesign( ) method.
Listing 25‑61 The collectDataSetDesign( ) method
protected DataSetDesign collectDataSetDesign(
DataSetDesign design )
{
if ( ! hasValidData( ) )
{
return design;
}
design.setQueryText( queryText.getText( ) );
savePage( design );
return design;
}