Understanding the sample CSV ODA user interface extension
The CSV ODA user interface extension described in this section illustrates how to create an ODA user interface plug-in using the Eclipse PDE. The following section describes the code-based extensions a developer must make to complete the development of the CSV ODA user interface extension, after defining the plug-in framework in the Eclipse PDE.
The CSV ODA user interface plug-in contains the following packages:
*org.eclipse.birt.report.data.oda.csv.ui
Contains the UiPlugin class, which is automatically generated by the PDE Manifest Editor when you create the plug-in project.
*org.eclipse.birt.report.data.oda.csv.ui.i18n
Contains the Messages class and the properties file, messages.properties, to generate the messages displayed in the user interface. The localized versions for these messages are in files that use the following naming syntax:
messages_<locale>.msg
*org.eclipse.birt.report.data.oda.csv.ui.impl
Contains the CustomDataSetWizardPage class, an automatically generated implementation of an ODA data set designer page, which supports creating or editing an ODA data set.
*org.eclipse.birt.report.data.oda.csv.ui.wizards
The wizards package contains the classes that create the user interface pages used to choose a data source and data set in BIRT Report Designer.
Implementing the ODA data source and data set wizards
BIRT Report Designer uses the Eclipse Data Tools Platform (DTP) ODA design-time framework and offers wizards that automatically generate customizable implementations. The DTP ODA framework defines two of the three extension points used in the CSV ODA user interface plug‑in:
*Connection profile
Defined in org.eclipse.datatools.connectivity.connectionProfile
*Data source and data set wizards
Defined in org.eclipse.datatools.connectivity.oda.design.ui.dataSource
The CSV ODA user interface plug-in also must implement the extension point for property pages defined in org.eclipse.ui.propertyPages.
The CSV ODA user interface plug-in uses the following abstract base classes in the org.eclipse.datatools.connectivity.oda.design.ui.wizards package to create the wizards that specify the data source and data set pages. An ODA user interface plug-in must extend these classes to provide the wizard pages with page control and related behavior:
*DataSourceEditorPage
Provides the framework for implementing an ODA data source property page
*DataSourceWizardPage
Provides the framework for implementing an ODA data source wizard page
*DataSetWizardPage
Provides the framework for implementing an ODA data set wizard page
Understanding the org.eclipse.birt.report.data.oda.csv.ui.impl package
This customizable page provides a simple Query Text control for user input. The page extends org.eclipse.datatools.connectivity.oda.design.ui.wizards.DataSetWizardPage in the DTP ODA design-time framework to support updating an ODA data set design instance using query metadata.
Understanding the org.eclipse.birt.report.data.oda.csv.ui.wizards package
The org.eclipse.birt.report.data.oda.csv.ui.wizards package in the CSV ODA user interface extension example implements the following classes:
*Constants
Defines the constants for the data source connection properties defined in the run-time drive implementation, org.eclipse.birt.report.data.oda.csv.
*CSVFilePropertyPage
Extends DataSourceEditorPage. This class creates and initializes the editor controls for the property page used to specify the ODA data source. The class updates the connection profile properties with the values collected from the page.
*CSVFileSelectionPageHelper
Specifies the page layout and sets up the control that listens for user input and verifies the location of the CSV data source file.
*CSVFileSelectionWizardPage
Extends DataSourceWizardPage. This class creates and initializes the controls for the data source wizard page. The class sets the select file message and collects the property values.
*FileSelectionWizardPage
Extends DataSetWizardPage. This class creates and initializes the controls for the data set wizard page and specifies the page layout. The class connects to the data source, executes a query, retrieves the metadata and result set, and updates the data‑set design.
Understanding Constants
The Constants class defines the following variables for the data source connection properties defined in org.eclipse.birt.report.data.oda.csv:
*ODAHOME specifies the CSV ODA file path constant, HOME.
*ODA_DEFAULT_CHARSET specifies the default character set as 8-bit Unicode Transformation Format (UTF-8).
*DEFAULT_MAX_ROWS sets the default maximum number of rows that can be retrieved from the data source.
Listing 20‑18 shows the code for the Constants class.
Listing 20‑18 The Constants class
public class Constants {
 
public static String ODAHOME="HOME";
public static String ODA_DEFAULT_CHARSET = "UTF-8";
public static int DEFAULT_MAX_ROWS = 1000;
 
}
Understanding CSVFilePropertyPage
CSVFilePropertyPage extends the DataSourceEditorPage class, implementing the following methods to provide page editing functionality for the CSV ODA data source property page:
*createAndInitCustomControl( ) method performs the following tasks:
*Instantiates a CSVFileSelectionPageHelper object
*Specifies the page layout and sets up the editing control by calling CSVFileSelectionPageHelper.createCustomControl( ) and initCustomControl( ) methods
Listing 20‑19 shows the code for the createAndInitCustomControl( ) method.
Listing 20‑19 The createAndInitCustomControl( ) method
protected void createAndInitCustomControl
( Composite parent, Properties profileProps )
{
if( m_pageHelper == null )
m_pageHelper =
new CSVFileSelectionPageHelper( this );
m_pageHelper.createCustomControl( parent );
m_pageHelper.initCustomControl( profileProps );
if( ! isSessionEditable( ) )
getControl( ).setEnabled( false );
}
*collectCustomProperties( ) updates the connection profile properties with the values collected from the page by calling CSVFileSelectionPageHelper.collectCustomProperties( ) method, as shown in Listing 20‑20.
Listing 20‑20 The collectCustomProperties( ) method
public Properties collectCustomProperties
( Properties profileProps )
{
if( m_pageHelper == null )
return profileProps;
return m_pageHelper.collectCustomProperties
( profileProps );
}
Understanding CSVFileSelectionPageHelper
CSVFileSelectionPageHelper provides auxiliary processing for the CSVFilePropertyPage and CSVFileSelectionWizardPage classes. CSVFileSelectionPageHelper implements the following methods:
*createCustomControl( ) performs the following tasks:
*Sets up the composite page layout
*Calls the setupFileLocation( ) method that sets up a control to listen for user input and verify the location of the CSV data source file
Listing 20‑21 shows the code for the createCustomControl( ) method.
Listing 20‑21 The createCustomControl( ) method
void createCustomControl( Composite parent )
{
Composite content = new Composite( parent, SWT.NULL );
GridLayout layout = new GridLayout( 2, false );
content.setLayout(layout);
setupFileLocation( content );
}
*setupFileLocation( ) performs the following tasks:
*Sets up the label and the grid data object in the page layout
*Sets up the control that listens for user input and verifies the location of the CSV data source file
Listing 20‑22 shows the code for the setupFileLocation( ) method.
Listing 20‑22 The setupFileLocation( ) method
private void setupFileLocation( Composite composite )
{
Label label = new Label( composite, SWT.NONE );
label.setText( Messages.getString
( "label.selectFile" ) );
 
GridData data = new GridData( GridData.FILL_HORIZONTAL );
 
fileName = new Text( composite, SWT.BORDER );
fileName.setLayoutData( data );
setPageComplete( false );
 
fileName.addModifyListener(
new ModifyListener( )
{
public void modifyText( ModifyEvent e )
{
verifyFileLocation();
}
} );
}
*collectCustomProperties( ) sets the data source directory property in the connection profile, as shown in Listing 20‑23.
Listing 20‑23 The collectCustomProperties( ) method
Properties collectCustomProperties( Properties props )
{
if( props == null )
props = new Properties( );
props.setProperty( CommonConstants.CONN_HOME_DIR_PROP,
getFolderLocation( ) );
return props;
}
*initCustomControl( ) initializes the data source wizard control to the location of the data source file, as shown in Listing 20‑24.
Listing 20‑24 The initCustomControl( ) method
void initCustomControl( Properties profileProps )
{
if( profileProps == null || profileProps.isEmpty( ) ||
fileName == null )
return;
String folderPath = profileProps.getProperty(
CommonConstants.CONN_HOME_DIR_PROP );
if( folderPath == null )
folderPath = EMPTY_STRING;
fileName.setText( folderPath );
verifyFileLocation( );
}
Understanding CSVFileSelectionWizardPage
The CSVFileSelectionWizardPage class extends the DataSourceWizardPage class, implementing the following methods to provide the functionality for the CSV ODA data source wizard page:
*The createPageCustomControl( ) method performs the following tasks:
*Instantiates a CSVFileSelectionPageHelper object
*Specifies the page layout and sets up the wizard page control by calling CSVFileSelectionPageHelper.createCustomControl( ) method
*Calls CSVFileSelectionPageHelper.initCustomControl( ) to initialize the control to the location of the data source file
Listing 20‑25 shows the code for the createPageCustomControl( ) method.
Listing 20‑25 The createPageCustomControl( ) method
public void createPageCustomControl( Composite parent )
{
if( m_pageHelper == null )
m_pageHelper =
new CSVFileSelectionPageHelper( this );
m_pageHelper.createCustomControl( parent );
m_pageHelper.initCustomControl( m_csvFileProperties );
}
*The collectCustomProperties( ) method instantiates a Properties object to contain the CSV data source properties information, as shown in Listing 20‑26.
Listing 20‑26 The collectCustomProperties( ) method
public Properties collectCustomProperties( )
{
if( m_pageHelper != null )
return m_pageHelper.collectCustomProperties(
m_csvFileProperties );
return ( m_csvFileProperties != null ) ?
m_csvFileProperties : new Properties( );
}
Understanding FileSelectionWizardPage
The FileSelectionWizardPage class extends the DataSetWizardPage class, implementing the following methods to provide the functionality for the CSV ODA data set wizard page:
*The createPageControl( ) method performs the following tasks:
*Specifies the page layout and sets up the wizard page control
*Gets the data source properties
*Calls populateAvailableList( ) to update the data set design
Listing 20‑27 shows the code for the createPageControl( ) method.
Listing 20‑27 The createPageControl( ) method
private Control createPageControl( Composite parent )
{
Composite composite = new Composite( parent, SWT.NULL );
FormLayout layout = new FormLayout( );
composite.setLayout( layout );
FormData data = new FormData( );
data.left = new FormAttachment( 0, 5 );
data.top = new FormAttachment( 0, 5 );
fileName = new Text( composite, SWT.BORDER );
fileName.setLayoutData( data );
Properties dataSourceProps =
getInitializationDesign( ).getDataSourceDesign( )
.getPublicProperties( );
fileName.setText( ( String )(
dataSourceProps.getProperty( Constants.ODAHOME )));
data = new FormData( );
data.top = new FormAttachment(
fileName, 10, SWT.BOTTOM );
data.left = new FormAttachment( 0, 5 );
data.right = new FormAttachment( 47, -5 );
data.bottom = new FormAttachment( 100, -5 );
data.width = DEFAULT_WIDTH;
data.height = DEFAULT_HEIGHT;
m_availableList = new List( composite,
SWT.MULTI | SWT.BORDER |
SWT.H_SCROLL | SWT.V_SCROLL );
m_availableList.setLayoutData( data );
m_selectedFile =
new File(( String )(
dataSourceProps.getProperty( Constants.ODAHOME )));
populateAvailableList( );
return composite;
}
*getQuery( ) method builds the query for the data set by performing the following tasks:
*Gets the table name from the file object
*Appends the table name to a query that selects all the columns using a wildcard
*Appends the column list then the table name to a query that selects specific columns
*Returns the query text
Listing 20‑28 shows the code for the getQuery( ) method.
Listing 20‑28 The getQuery( ) method
private String getQuery( )
{
String tableName = null;
StringBuffer buf = new StringBuffer( );
File file = m_selectedFile;
if(file != null)
{
tableName = file.getName( );
}
if(tableName != null)
{
if(m_availableList.getItemCount( ) == 0)
{
buf.append("select * from ").append(tableName);
}
else
{
buf.append("select ");
String[ ] columns = m_availableList.getItems( );
for(int n = 0; n < columns.length; n++)
{
buf.append(columns[n]);
if(n < columns.length - 1)
{
buf.append(", ");
}
}
buf.append(" from ").append(tableName);
}
}
return buf.toString( );
}
*getQueryColumnNames( ) method performs the following tasks:
*Instantiates the CSVFileDriver
*Prepares the query and gets the results set metadata using the CSV ODA run-time driver and data source connection properties settings
*Gets the column count
*Iterates through the metadata results to get the column names and return the results
Listing 20‑29 shows the code for the getQueryColumnNames( ) method.
Listing 20‑29 The getQueryColumnNames( ) method
private String[ ] getQueryColumnNames(
String queryText, File file )
{
 
IDriver ffDriver = new CSVFileDriver( );
IConnection conn = null;
 
try
{
conn = ffDriver.getConnection( null );
 
IResultSetMetaData metadata =
getResultSetMetaData( queryText, file, conn );
int columnCount = metadata.getColumnCount( );
 
if( columnCount == 0 )
return null;
String[ ] result = new String[columnCount];
 
for( int i = 0; i < columnCount; i++)
result[i] = metadata.getColumnName( i + 1 );
return result;
}
catch( OdaException e )
{
setMessage( e.getLocalizedMessage( ), ERROR );
disableAll( );
return null;
}
finally
{
closeConnection( conn );
}
}
*getResultSetMetaData( ) method performs the following tasks:
*Sets up the Properties object with the location of the data source file
*Opens the connection to the data source
*Sets up a Query object and prepares the query text
*Executes the query
*Returns the metadata
Listing 20‑30 shows the code for the getResultSetMetaData( ) method.
Listing 20‑30 The getResultSetMetaData( ) method
private IResultSetMetaData getResultSetMetaData( String queryText, File file, IConnection conn ) throws OdaException
{
java.util.Properties prop = new java.util.Properties( );
prop.put( CommonConstants.CONN_HOME_DIR_PROP,
file.getParent( ) );
conn.open( prop );
IQuery query = conn.newQuery( null );
query.setMaxRows( Constants.DEFAULT_MAX_ROWS );
query.prepare( queryText );
query.executeQuery( );
return query.getMetaData( );
}
*setResultSetMetaData( ) method updates the data set page design with metadata returned by the query by performing the following tasks:
*Calls the DesignSessionUtil.toResultSetColumnsDesign( ) method to convert the run-time metadata to a design-time ResultSetColumns object
*Obtains a ResultSetDefinition object from the design factory to use in populating the data set page design with the metadata definitions
*Calls the resultSetDefn.setResultSetColumns( ) method to set the reference to ResultSetColumns object, containing the metadata content
*Assigns the result set definition to the data set design
Listing 20‑31 shows the code for the setResultSetMetaData( ) method.
Listing 20‑31 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 );
}
*savePage( ) method performs the following tasks:
*Instantiates the CSVFileDriver
*Gets the result set metadata
*Updates the data set design with the metadata
*Closes the connection
Listing 20‑32 shows the code for the savePage( ) method.
Listing 20‑32 The savePage( ) method
private void savePage( DataSetDesign dataSetDesign )
{
String queryText = getQuery( );
dataSetDesign.setQueryText( queryText );
IConnection conn = null;
try
{
IDriver ffDriver = new CSVFileDriver( );
conn = ffDriver.getConnection( null );
IResultSetMetaData metadata =
getResultSetMetaData( queryText, m_selectedFile,
conn );
setResultSetMetaData( dataSetDesign, metadata );
}
catch( OdaException e )
{
dataSetDesign.setResultSets( null );
}
finally
{
closeConnection( conn );
}
}