Chapter 18. Developing a Report Rendering Extension

This chapter describes how to develop a report rendering extension using the Eclipse PDE with a sample CSV report rendering extension as the example. You learn how to develop a BIRT report rendering extension in the following sections:

  • Understanding a report rendering extension

  • Developing the CSV report rendering extension

  • Understanding the sample CSV report rendering extension

  • Testing the CSV report rendering plug-in

Understanding a report rendering extension

BIRT Report Engine provides report rendering extensions that render a report in HTML and PDF. In BIRT release 2.1, the BIRT report rendering extension API supports rendering a report in a customized format, such as CSV.

This chapter provides a sample implementation of a customized CSV report rendering extension, org.eclipse.birt.report.engine.emitter.csv. The sample code creates a BIRT plug-in that writes the data contents of a report to a file. For reference documentation on the BIRT report rendering API, see the Javadoc for the org.eclipse.birt.report.engine.emitter and org.eclipse.birt.report.engine.content packages in BIRT Programmer Reference in Eclipse Help.

The BIRT Report Engine does not run as an Eclipse plug-in. BIRT implements a separate plug-in loading framework in the report engine environment. This framework runs independently of the Eclipse run-time environment, giving the BIRT Report Engine complete control of report execution.

A BIRT engine plug-in typically loads and runs in the BIRT Report Engine environment rather than the Eclipse run-time environment. A BIRT engine plug-in extension is functionally similar to an Eclipse plug-in extension.

A rendering extension adds an emitter to the BIRT framework by implementing the extension point, org.eclipse.birt.report.engine.emitters. This extension point enables support for a new output format in the presentation engine. The BIRT plug-in registry uses this extension point to discover all supported output formats specified in the report engine environment. The XML schema file, org.eclipse.birt.report.engine/schema/emitters.exsd, describes the extension point.

Developing the CSV report rendering extension

The CSV report rendering extension extends the functionality defined by the org.eclipse.birt.report.engine.emitter package. This package is part of the org.eclipse.birt.report.engine plug-in. In developing the CSV report rendering extension, you perform the following tasks:

  • Download the required BIRT source code from the Eclipse CVS repository.

  • Create a CSV report rendering extension project in the Eclipse PDE.

  • Define the dependencies.

  • Declare the emitters extension point.

  • Implement the emitter interfaces.

  • Test the extension in the run-time environment.

You can download the source code for the CSV report rendering extension example at http://www.actuate.com/birt/contributions.

Downloading BIRT source code from the CVS repository

The CSV report rendering extension depends on the following BIRT plug-ins:

  • org.eclipse.birt.core

  • org.eclipse.birt.report.engine

  • org.eclipse.birt.report.model

The CSV report rendering extension requires changes to the org.eclipse.birt.report.engine plug-in, so you must download the source code for this plug-in from the CVS repository.

To compile, you do not need the source code for the other required plug-ins. You can configure the system to use the JAR files in the $INSTALL_DIReclipseplugins folder.

These plug-ins must be in the classpath to compile successfully. To debug, you may need the source code for all required BIRT plug-ins.

Creating a CSV report rendering plug-in project

Create a new plug-in project for the CSV report rendering extension using the Eclipse PDE.

How to create the CSV report rendering plug-in project

  1. From the Eclipse PDE menu, choose File →New →Project. New Project appears.

  2. On New Project, select Plug-in Project. Choose Next. New Plug-in Project appears.

  3. In Plug-in Project, modify the settings, as shown in Table 18-1.

    Table 18-1. Values for Plug-in Project fields

    Section

    Option

    Value

    Plug-in Project

    Project name

    org.eclipse.birt.report.engine.emitter.csv

     

    Use default location

    Selected

     

    Location

    Not available when you select Use default location

    Project Settings

    Create a Java project

    Selected

     

    Source folder

    src

     

    Output folder

    bin

    Target Platform

    Eclipse version

    3.2

     

    an OSGi framework

    Selected Equinox

    Plug-in Project appears as shown in Figure 18-1. Choose Next. Plug-in Content appears.

    Values for Plug-in Project

    Figure 18-1. Values for Plug-in Project

  4. In Plug-in Content, modify the settings, as shown in Table 18-2.

    Table 18-2. Values for Plug-in Content fields

    Section

    Option

    Value

    Plug-in Properties

    Plug-in ID

    org.eclipse.birt.report.engine.emitter.csv

     

    Plug-in Version

    1.0.0

     

    Plug-in Name

    BIRT CSV Emitter

     

    Plug-in Provider

    yourCompany.com or leave blank

     

    Classpath

    csvEmitter.jar or leave blank

    Plug-in Options

    Generate an activator, a Java class that controls the plug-in’s life cycle

    Selected

     

    Activator

    org.eclipse.birt.report.engine.emitter.csv.CsvPlugin

     

    This plug-in will make contributions to the UI

    Deselected

    Rich Client Application

    Would you like to create a rich client application?

    No

    Plug-in Content appears as shown in Figure 18-2. Choose Finish.

    Values for Plug-in Content

    Figure 18-2. Values for Plug-in Content

    The CSV report rendering extension project appears in the Eclipse PDE workbench, as shown in Figure 18-3.

    CSV report rendering extension project

    Figure 18-3. CSV report rendering extension project

Defining the dependencies for the CSV report rendering extension

To compile and run the CSV report rendering example, you need to specify the list of plug-ins that must be available on the classpath of the extension.

How to specify the dependencies

  1. On PDE Manifest Editor, choose Overview.

  2. In Plug-in Content, choose Dependencies. Required Plug-ins contains the following plug-in:

    org.eclipse.core.runtime
  3. In Required Plug-ins, perform the following tasks:

    1. Select org.eclipse.core.runtime and choose Remove.

      org.eclipse.core.runtime no longer appears in Required Plug-ins.

    2. Choose Add. Plug-in Selection appears.

    3. In Plug-in Selection, hold down CTRL and select the following plug-ins:

      • org.eclipse.birt.core

      • org.eclipse.birt.report.model

      • org.eclipse.birt.report.engine

      Choose OK. Dependencies appears as shown in Figure 18-4.

      The Dependencies page

      Figure 18-4. The Dependencies page

    The order of the list determines the sequence in which a plug-in loads at run time. Use Up and Down to change the loading order as necessary, as shown in Figure 18-4. The CSV report rendering extension does not require any changes to the loading order if you selected the required plug-ins in the order listed in step 3.

Declaring the emitters extension point

In this step, you specify the extension point required to implement the CSV report rendering extension and add the extension element details. The extension point, org.eclipse.birt.report.engine.emitters, specifies the following properties that identify the extension point:

  • ID

    Optional identifier of the extension instance

  • Name

    Optional name of the extension instance

  • Point

    Fully qualified identifier of the extension point

The extension point defines an emitter that specifies the output format for the plug-in, requiring you to define the following extension element properties:

  • class

    Java class that implements the IContentEmitter interface

  • format

    Output format that the emitter supports, such as csv

  • mimeType

    MIME type for the supported output format, such as text/csv

  • id

    Optional identifier of the emitter extension

You specify the extension point and extension element details using the Eclipse PDE.

How to specify the extension point

  1. On PDE Manifest Editor, choose Extensions.

  2. In All Extensions, choose Add. New Extension—Extension Point Selection appears.

  3. In Available extension points, select the following plug-in:

    org.eclipse.birt.report.engine.emitters

    Choose Finish. Extensions appears, as shown in Figure 18-5.

    Emitter plug-in extension on the Extensions page

    Figure 18-5. Emitter plug-in extension on the Extensions page

    All Extensions lists the extension point, org.eclipse.birt.report.engine.emitters. Extension Details contains the list of extension details specified in the XML schema file, emitters.exsd.

  4. In All Extensions, right-click the extension point, org.eclipse.birt.report.engine.emitters, and choose the extension element, emitter, as shown in Figure 18-6.

    Selecting the emitter extension element

    Figure 18-6. Selecting the emitter extension element

    Extension element, emitter, appears in All Extensions.

  5. In Extension Element Details, specify the properties for the emitter extension element, emitter, as shown in Table 18-3.

    Table 18-3. Property values for the emitter extension element

    Property

    Value

    class

    org.eclipse.birt.report.engine.emitter.csv.CSVReportEmitter

    format

    csv

    mimeType

    text/csv

    id

    org.eclipse.birt.report.engine.emitter.csv

    Extensions appears as shown in Figure 18-7. PDE Manifest Editor automatically updates plugin.xml.

    Property values for the emitter extension

    Figure 18-7. Property values for the emitter extension

Understanding the sample CSV report rendering extension

The CSV report rendering extension described in this chapter is a simplified example that illustrates how to create a report rendering plug-in using the Eclipse PDE. The extension extends the report emitter interfaces and XML writer in org.eclipse.birt.report.engine.emitter. The example is based on the plug-in, org.eclipse.report.engine.emitter.html, which is part of the BIRT framework. BIRT release 2.1 also provides a data extraction feature built into the UI that can export data from a report document in CSV, tab-separated values (TSV), and Extensible Markup Language (XML) formats.

The CSV report rendering extension example exports only the data in the table controls to the CSV output file. The lines of the CSV output file contain only column data separated by commas. The sample CSV report design cannot contain images, charts, or hyperlinks.

The extension example creates the CSV output file in the same folder as the exported report. The output file name is the name of the report with a .csv extension. The extension provides only limited error checking.

The following section provides a general description of the code-based extensions a developer must make to complete the development of the CSV report rendering extension after defining the plug-in framework in the Eclipse PDE.

Implementing the emitter interfaces

The org.eclipse.birt.report.engine.emitter plug-in defines the report emitter interfaces that XML writer uses to render the elements of the report items in a report container, such as a page, table, row, column, cell, label, image, or extended item. The CSV report rendering extension implements parts of the following interfaces and classes in the emitter plug-in:

  • IContentEmitter

    Defines the interface for the start and end processing that renders the report items. ContentEmitterAdapter is the adapter class that implements this interface.

  • IEmitterServices

    Defines the interface an emitter uses to access the following items:

    • Emitter configuration

      Provides information on the engine emitter configuration

    • Rendering context

      Provides information on the engine rendering context

    • Rendering options

      Implements the org.eclipse.birt.report.engine.api.IRenderOption interface, specifying the following output items:

      • Format, such as PDF or HTML

      • File name to use for output

      • Stream for writing to the output file

      • Miscellaneous settings

    • Runnable report design

      Defines the methods that get the report design handle, images, and property values, such as report name, title, and description. Specified by an implementation of the interface, org.eclipse.birt.report.engine.api.IReportRunnable.

    • Engine task

      Defines the set of operations specified for a unit of work. Implements the org.eclipse.birt.report.engine.api interface, providing access to the following items:

      • Task identifier

      • Locale

      • Application context

      • Parameters

      • Report engine

      • Scriptable Java object

      EngineEmitterServices is the adapter class that implements this interface.

    • XMLWriter

      Outputs content in XML format. CSV report rendering extension extends XMLWriter to write in CSV format. Performs the following operations:

      • Opens and closes the output stream, using an instance of java.io.PrintWriter class

      • Starts and finishes the java.io.PrintWriter processing

      • Returns encoding information

      • Opens and closes the printing of an XML tag, including any attributes and encoded content

      • Sets up the java.util.logging.Logger object and logs messages at the specified logging levels

As a best practice, Eclipse recommends extending the adapter class rather than implementing an interface directly. An adapter class provides stub implementations of all the methods in the interface. If you implement an interface directly and the interface changes, you must add any new methods to the code to avoid compiler errors even if you do not plan to use the methods. Extending the adapter class insulates the developer from this problem. A class that extends an adapter compiles, but does not provide the new behavior automatically. You must be aware of the changes to the interface to take advantage of the new functionality and extend the code.

Implementing the content interfaces

The package, org.eclipse.birt.report.engine.content, defines the interfaces for BIRT report items that BIRT Report Engine uses to pass content an emitter. These content interfaces provide a common protocol for rendering an instance of a content object.

The CSV report rendering extension implements some of these interfaces. Each interface defines accessor methods for properties depending on the type of the content object, as shown in Table 18-4.

Table 18-4. Interfaces that pass content to an emitter

Interface

Properties

IBandContent

Header and footer content in a table or group

ICellContent

Row and column spans.

IContainerContent

No defined fields or methods. Inherits fields and methods from the superinterfaces, IContent, IElement, and CSSStylableElement.

IDataContent

Label and help keys, text, and values.

IElement

Parent or children of a content element.

IForeignContent

Raw types and values not handled by BIRT Report Engine.

IImageContent

URI, MIME type, image source, image map, help key, extension, alternative key and text.

ILabelContent

Label and help keys and text.

IPageContent

Page number, dimensions, orientation, and content style.

IRowContent

Table, group, band, and row.

ITableBandContent

Table and group headers and footers, and band detail.

ITableContent

Table band content, caption, column, and column count.

ITextContent

Text.

Most of the interfaces in the org.eclipse.birt.report.engine.content package, with the exception of interfaces such as IContentVisitor, IElement, and IReportContent, inherit from the superinterface, org.eclipse.birt.report.engine.content.IContent. IContent specifies methods that provide access to the following additional interfaces and properties in the package:

  • IContentVisitor

    Defines a visitor interface, typically used by a buffered emitter. The visitor design pattern separates content objects and their operations into different classes. Implementing a visitor design pattern allows a developer to change the operations performed on a collection of objects without changing the structure of the objects and recompiling the object code.

  • IBounds

    Describes the geometric properties of the content.

  • ContentType

    Lists the constant field values used to identify content types.

  • IHyperlinkAction

    Defines the interface that allows BIRT Report Engine to pass hyperlink information to an emitter.

The following interfaces define additional functionality in the org.eclipse.birt.report.engine.content package:

  • IStyle

    Defines the accessor methods for ROM style properties

  • IReportContent

    Creates report item content, using the following components:

    • Report design

      An instance of org.eclipse.birt.report.engine.ir.Report

    • Table of contents (TOC) node

      An instance of org.eclipse.birt.report.engine.api.TOCNode

    • CSS engine

      An instance of org.eclipse.birt.report.engine.css.engine.CSSEngine

Understanding the CSV report rendering extension package

The implementation package for the CSV report rendering extension example, org.eclipse.birt.report.engine.emitter.csv, contains the following classes:

  • CSVReportEmitter

    Extends org.eclipse.birt.report.engine.emitter.ContentEmitterAdapter. CSVReportEmitter handles the start and end processing that renders the report container.

  • CSVTags.java

    Defines the comma and new line Strings used when writing to the CSV file.

  • CSVWriter

    Extends org.eclipse.birt.report.engine.emitter.XMLWriter. CSVWriter performs the following operations:

    • Overrides XMLWriter.closeTag( ) to set up for CSV output processing

    • Prints CSV content, using a call to java.io.PrintWriter.print( )

  • CSVPlugin

    Defines the methods for starting, managing, and stopping a plug-in instance.

The following section contains more specific information about the implementation details for the classes in the CSV report rendering extension package.

Understanding CSVReportEmitter

CSVReportEmitter is the class that extends ContentEmitterAdapter to output the text content of the report items to a CSV file. CSVReportEmitter instantiates the writer and emitter objects.

CSVReportEmitter implements the following methods:

  • CSVReportEmitter( ) instantiates the CSV report emitter class as an org.eclipse.birt.report.engine.presentation.ContentEmitterVisitor object, to perform emitter operations, as shown in Listing 18-1.

    Example 18-1. The CSVReportEmitter( ) constructor

    public CSVReportEmitter( )
    {
      contentVisitor = new ContentEmitterVisitor( this );
    }
  • initialize( ) performs the following operations required to create an output stream that writes the text contents of the report to the CSV file:

    • Obtains a reference to the IEmitterServices interface. Instantiates the file and output stream objects, using the specified settings.

    • Instantiates the CSV writer object.

    Listing 18-2 shows the initialize( ) method.

    Example 18-2. The initialize( ) method

    public void initialize( IEmitterServices services )
    {
       this.services = services;
       Object fd = services.getOption
          ( RenderOptionBase.OUTPUT_FILE_NAME );
       File file = null;
       try
       {
          if ( fd != null )
          {
             file = new File( fd.toString( ) );
             File parent = file.getParentFile( );
             if ( parent != null && !parent.exists( ) )
             {
                parent.mkdirs( );
             }
             out = new BufferedOutputStream( new
                FileOutputStream( file ) );
          }
       }
       catch ( FileNotFoundException e )
       {
          logger.log( Level.WARNING, e.getMessage( ), e );
       }
       if ( out == null )
       {
       Object value = services.getOption
          ( RenderOptionBase.OUTPUT_STREAM );
       if ( value != null && value instanceof OutputStream )
       {
          out = (OutputStream) value;
       }
       else
       {
          try
          {
             file = new File( REPORT_FILE );
             out =
               new BufferedOutputStream
                  ( new FileOutputStream( file ) );
          }
          catch ( FileNotFoundException e )
          {
             logger.log( Level.SEVERE, e.getMessage( ), e );
          }
        }
      }
      writer = new CSVWriter( );
    }
  • start( ) performs the following operations:

    • Obtains a reference to the IReportContent interface, containing accessor methods that get the interfaces to the report content emitters

    • Sets a logging level and writes to the log file

    • Opens the output file and specifies the encoding scheme as UTF-8

    • Starts the CSV writer

    Listing 18-3 shows the start( ) method.

    Example 18-3. The start( ) method

    public void start( IReportContent report )
    {
       logger.log( Level.FINE,
         "[CSVReportEmitter]  Start emitter." );
       this.report = report;
       writer.open( out, "UTF-8" );
       writer.startWriter( );
    }
  • end( ) performs the following operations:

    • Sets a logging level and writes to the log file

    • Ends the write process and closes the CSV writer

    • Closes the output file

Listing 18-4 shows the end( ) method.

Example 18-4. The end( ) method

public void end( IReportContent report )
{
   logger.log( Level.FINE,
      "[CSVReportEmitter] End report." );
   writer.endWriter( );
   writer.close( );
   if( out != null )
   {
     try
     {
        out.close( );
     }
     catch ( IOException e )
     {
        logger.log( Level.WARNING, e.getMessage( ), e );
     }
   }
}

Understanding the other CSVReportEmitter methods

The CSVReportEmitter class defines the following additional methods, called at different phases of the report generation process, that identify hidden content and provide access to emitters, render options, and style information to facilitate BIRT Report Engine processing:

  • push( ), pop( ), and peek( )

    The CSV plug-in does not export hidden report elements. You can use the IStyle interface to obtain information about the visible format of a content object by pushing and popping this object on and off a stack.

    In Listing 18-5, while the IStyle object is on the stack, peek( ) uses IStyle.getVisibleFormat( ) to examine the visible format property. peek( ) determines if the current content object is visible and returns the Boolean variable, isHidden, to indicate the status of the item.

    Example 18-5. The peek( ) method

    public boolean peek( IStyle style )
    {
       boolean isHidden = false;
       if ( !stack.empty( ) )
       {
          isHidden =
             ( (Boolean) stack.peek( ) ).booleanValue( );
       }
       if ( !isHidden )
       {
          String formats = style.getVisibleFormat( );
          if ( formats != null
            && ( formats.indexOf
                  ( EngineIRConstants.FORMAT_TYPE_VIEWER ) >=
                  0 || formats.indexOf
                        ( BIRTConstants.BIRT_ALL_VALUE ) >= 0 ) )
          {
            isHidden = true;
          }
       }
       return isHidden;
    }
  • startTable( )

    When writing to the CSV file, the CSV rendering extension must consider the cell position in the row because all the cells end with a comma except the last cell in the row.

    startTable( ) uses ITableContent.getColumnCount( ) to get information about table column numbers and to initialize the protected columnNumbers variable, as shown in Listing 18-6.

    Example 18-6. The startTable( ) method

    public void startTable( ITableContent table )
    {
       assert table != null;
       columnNumbers = table.getColumnCount();
    ...
    }
  • startRow( )

    At the start of each row, startRow( ) performs the following operations:

    • Calls isRowInFooterBand( ) to determine if the row is in the header or footer band of a table or group

    • Sets the currentColumn indicator to 0

    Listing 18-7 shows the startRow( ) code.

    Example 18-7. The startRow( ) method

    public void startRow( IRowContent row )
    {
       assert row != null;
       if ( isRowInFooterBand( row ) )
          exportTableElement = false;
       IStyle mergedStyle = row.getStyle( );
       push( mergedStyle );
       if ( isHidden( ) )
       {
          return;
       }
       currentColumn = 0;
    }
  • isRowInFooterBand( )

    If the row is an instance of band content, isRowInFooterBand( ) checks the band type. If the band type is a footer, the method returns true, as shown in Listing 18-8.

    Example 18-8. The isRowInFooterBand( ) method

    boolean isRowInFooterBand( IRowContent row )
    {
       IElement parent = row.getParent( );
       if ( !( parent instanceof IBandContent ) )
       {
          return false;
       }
       IBandContent band = ( IBandContent )parent;
       if ( band.getBandType( ) == IBandContent.BAND_FOOTER )
       {
          return true;
       }
       return false;
    }
  • startText( )

    If the element is exportable and not hidden, startText( ) writes the text value to the CSV output file, as shown in Listing 18-9.

    Example 18-9. The startText( ) method

    public void startText( ITextContent text )
    {
       IStyle mergedStyle = text.getStyle( );
       if ( peek( mergedStyle ) )
       {
          return;
       }
       logger.log( Level.FINE,
          "[CSVReportEmitter] Start text" );
       String textValue = text.getText( );
    
       if ( exportTableElement )
       {
          writer.text( textValue );
       }
    }
  • endCell( )

    If the current cell is not the last column in the row and the element is exportable and not hidden, endCell( ) writes a comma to the CSV output file, as shown in Listing 18-10.

    Example 18-10. The endCell( ) method

    public void endCell( ICellContent cell )
    {
       if ( isHidden( ) )
       {
          return;
       }
       logger.log( Level.FINE,
          "[CSVReportEmitter] End cell." );
    
       if ( ( currentColumn < columnNumbers )
          && exportTableElement )
       {
          writer.closeTag( CSVTags.TAG_COMMA );
       }
    }
  • endRow( )

    At the end of each row, if the element is exportable and not hidden, endRow( ) writes a new line or carriage return to the CSV output file, as shown in Listing 18-11.

    Example 18-11. The endRow( ) method

    public void endRow( IRowContent row )
    {
       if ( pop( ) )
       {
         return;
       }
       if ( exportTableElement )
       writer.closeTag( CSVTags.TAG_CR );
       exportTableElement = true;
    }

Understanding CSVTags

The CSVTags class defines the contents of the comma and new line tags, as shown in Listing 18-12.

Example 18-12. The CSVTags class

public class CSVTags
{
   public static final String TAG_COMMA = "," ;
   public static final String TAG_CR = "
" ;
}

Understanding CSVWriter

The CSVWriter class extends org.eclipse.birt.report.engine.emitter.XMLWriter, overwriting the closeTag( ) method to write the closing tags defined in CSVTags, as shown in Listing 18-13.

Example 18-13. The closeTag( ) method

public void closeTag( String tagName )
{
   super.printWriter.print( tagName );
}

Understanding the BIRT report engine API package

In addition to the rendering classes, implementing the CSV report rendering extension requires making changes to the org.eclipse.birt.report.engine.api package. The following changes create and expose the API for the CSV rendering option developed in the org.eclipse.birt.report.engine.emitter.csv package:

  • RenderOptionBase

    Add the CSV output format to the format definitions in RenderOptionBase.

  • CSVRenderOption

    Create the class, org.eclipse.birt.report.engine.api.CSVRenderOption, to integrate the plug-in with BIRT Report Engine. This class defines CSV as an option in BIRT Report Engine.

  • EngineConstants

    Add the CSV render context to the list in EngineConstants.

The following section contains more specific information about the implementation details for the classes in the org.eclipse.birt.report.engine.api package.

Understanding RenderOptionBase

The org.eclipse.birt.report.engine.api.RenderOptionBase class implements the IRenderOption interface, which defines the rendering options for emitters. The accessor methods for this interface provide access to the following output options:

  • File name

  • Format

  • Stream

Add the new CSV format to the format definitions in org.eclipse.birt.report.engine.api.RenderOptionBase class, as shown in Listing 18-14.

Example 18-14. The RenderOptionBase class

public class RenderOptionBase implements IRenderOption {
   ...
   public static final String OUTPUT_FORMAT_HTML = "html";
   public static final String OUTPUT_FORMAT_PDF = "pdf";
   public static final String OUTPUT_FORMAT_FO = "fo";
   public static final String OUTPUT_FORMAT_CSV = "csv";
   ...

Understanding CSVRenderOption

The org.eclipse.birt.report.engine.api.CSVRenderOption class extends RenderOptionBase to add the CSV rendering option, as shown in Listing 18-15.

Example 18-15. The CSVRenderOption class

package org.eclipse.birt.report.engine.api;

public class CSVRenderOption extends RenderOptionBase {

   public static final String CSV = "CSV";

   public CSVRenderOption( ) {
   }
}

Understanding EngineConstants

The org.eclipse.birt.report.engine.api.EngineConstants class defines the CSV rendering context options to add the CSV rendering context option, as shown in Listing 18-16.

Example 18-16. The EngineConstants class

public class EngineConstants {
   public final static String APPCONTEXT_HTML_RENDER_CONTEXT =
      "HTML_RENDER_CONTEXT";
   public final static String APPCONTEXT_PDF_RENDER_CONTEXT =
      "PDF_RENDER_CONTEXT";
   public final static String APPCONTEXT_CSV_RENDER_CONTEXT =
      "CSV_RENDER_CONTEXT";
   ...
}

Testing the CSV report rendering plug-in

To test the CSV report rendering example, you create a Java application that runs a report design in an installation of the BIRT run-time engine. BIRT provides a run-time engine that runs in a stand-alone J2EE application server environment and a preview engine that runs in the BIRT Report Designer.

To test the CSV report rendering plug-in, you perform the following tasks:

  • Build the org.eclipse.birt.report.engine.emitter.csv and org.eclipse.birt.report.engine.api plug-ins.

  • Deploy the plug-ins to the BIRT run-time engine directory.

  • Launch a run-time instance of the Eclipse PDE.

  • Create a Java application that runs a report design and writes the report’s table data to a CSV file.

  • Create a report design containing a table that maps to a data source and data set.

  • Run the application and examine the output in the CSV file.

You must have previously installed the BIRT run-time engine in the test environment. For more information about downloading and installing the BIRT run-time engine, see the sections on installing the BIRT system earlier in this book or visit the Eclipse BIRT web site at http://www.eclipse.org/birt.

The following sections describe the steps required to build and export the plug-ins, launch the Eclipse PDE run-time environment, create the Java application and report design, and test the plug-in example.

How to build and export the org.eclipse.birt.report.engine.emitter.csv plug-in

On PDE Manifest Editor, perform the following tasks:

  1. On Build, specify the binary build configuration for the plug-in for org.eclipse.birt.report.engine.emitter.csv to include the following items:

    • plugin.xml

    • binorg.eclipse.birt.report.engine.emitter.csv

    • META-INFMANIFEST.MF

  2. On Overview, in Exporting, choose the Export Wizard and perform the following tasks:

    1. In Options, choose Package plug-ins as individual JAR archives, as shown in Figure 18-8.

      Exporting a plug-in option

      Figure 18-8. Exporting a plug-in option

    2. In Destination, choose the directory, $INSTALL_DIRirt-runtime-2_1_0Report Engine, as shown in Figure 18-9. Choose Finish.

      Exporting a plug-in to BIRT run-time engine

      Figure 18-9. Exporting a plug-in to BIRT run-time engine

How to build and deploy the org.eclipse.birt.report.engine plug-in

  1. Using Ant with the following BuildEngineAPI.xml file, create an archive containing the org.eclipse.birt.report.engine.api package with the modifications required to run the CSV emitter example.

    BuildEngineAPI.xml has two target operations:

    • Jar creates the engineapi.jar file from a defined file set.

    • Clean removes any objects created by previous build and archive operations, deleting the bin directory and engineapi.jar file.

    Listing 18-17 shows the BuildEngineAPI.xml code.

    Example 18-17. The BuildEngineAPI.xml code

    <project name="BIRT Engine Project" default="Jar"
       basedir=".">
       <description>BIRT Engine Project.</description>
    
       <property name="bin" location="bin"/>
       <property name="lib" location="lib"/>
    
       <target name="Jar" description="package engine files">
          <jar destfile="engineapi.jar">
             <fileset dir="${bin}">
                <include
                   name="org/eclipse/birt/report/engine/api/
                   *.class"/>
                <include name="org/eclipse/birt/report/engine/
                   util/
                   *.class"/>
                <include name="org/eclipse/birt/report/engine/
                   i18n/
                   *.class"/>
                <include name="org/eclipse/birt/report/engine/
                   i18n/
                   *.properties"/>
                <include name="org/eclipse/birt/report/engine/
                   api/impl/CascadingParameterGroupDefn.class"/>
                <include name="org/eclipse/birt/report/engine/
                   api/impl/ParameterDefn.class"/>
                <include name="org/eclipse/birt/report/engine/
                   api/impl/ParameterDefnBase.class"/>
                <include name="org/eclipse/birt/report/engine/
                   api/impl/ParameterGroupDefn.class"/>
                <include name="org/eclipse/birt/report/engine/
                   api/impl/ParameterSelectionChoice.class"/>
                <include name="org/eclipse/birt/report/engine/
                   api/impl/ScalarParameterDefn.class"/>
          </fileset>
          </jar>
       </target>
    
       <!-- Clean removes any objects created by
               previous build and archive operations -->
       <target name="Clean" description="clean up">
          <!-- Delete the ${bin} directory -->
          <delete dir="${bin}"/>
          <!-- Delete the engineapi.jar file /-->
          <delete dir="engineapi.jar"/>
       </target>
    
    </project>
  2. Copy engineapi.jar to $INSTALL_DIRirt-runtime-2_1_0Report Enginelib.

Launching the CSV report rendering plug-in

On PDE Manifest Editor, in Overview, the Testing section contains links to launch a plug-in as a separate Eclipse application in either Run or Debug mode. Figure 18-10 shows Overview for the CSV report rendering extension example in the host instance of the PDE workbench.

Overview information for the CSV report rendering extension

Figure 18-10. Overview information for the CSV report rendering extension

When the Eclipse PDE launches an Eclipse application, it creates the working directory, $INSTALL_DIReclipse untime-EclipseApplication, by default if the directory does not exist. For testing purposes, you can create a Java project in this workspace to run and render a report in CSV format. You can change the location of the working directory when you create the launch configuration for the Java application.

To execute, the report execution project must include the archive, org.eclipse.birt.report.engine.emitter.csv in $INSTALL_DIRirt-runtime-2_1_0Report Engineplugins, and the archive, engineapi.jar, in lib. Figure 18-11 shows the Eclipse run-time workbench with the report execution project completely specified, after a successful execution.

The report execution project in the Eclipse run-time workbench

Figure 18-11. The report execution project in the Eclipse run-time workbench

How to launch the CSV report rendering plug-in

  1. On Eclipse PDE Manifest Editor, in the Testing section of Overview, choose Launch an Eclipse application. The Eclipse PDE launches a run-time instance of the workbench.

  2. In the run-time instance of the Eclipse PDE workbench, choose Window →Open Perspective → Java. Java opens.

How to create the report execution project

  1. In Eclipse run-time workbench, choose File →New →Project. New Project appears.

  2. In New Project—Select a wizard, perform the following tasks:

    1. In Wizards, choose Java Project. Choose Next. Create a Java Project appears.

    2. In Create a Java Project, perform the following tasks:

      1. In Project name, type:

        ExecuteReport
      2. In Contents, select Create new project in workspace. Choose Next. Java Settings—Source appears.

    3. In Java Settings, choose Libraries. Java Settings—Libraries appears.

    4. In Libraries, perform the following tasks:

      1. Choose Add External JARS. JAR Selection opens.

      2. On JAR Selection, in Look in, navigate to $INSTALL_DIRirt -runtime-2_1_0Report Enginelib and, holding down CTRL, select the following libraries:

        • chartengineapi.jar

        • com.ibm.icu_3.4.4.1.jar

        • commons-cli-1.0.jar

        • commons-codec-1.3.jar

        • coreapi.jar

        • dataadapterapi.jar

        • dteapi.jar

        • engineapi.jar

        • flute.jar

        • js.jar

        • modelapi.jar

        • org.eclipse.emf.common_2.2.0.jar

        • org.eclipse.emf.ecore.xmi_2.2.0.jar

        • org.eclipse.emf.ecore_2.2.0.jar

        • sac.jar

        • scriptapi.jar

        Choose Open. Choose Finish. In Package Explorer, the ExecuteReport project appears.

How to create the Java report execution class

  1. In Eclipse run-time workbench, choose File →New →Class. New Java Class appears.

  2. On New Java Class, perform the following tasks:

    1. In Source folder, type:

      ExecuteReport
    2. In Which method stubs would you like to create?, perform the following tasks:

      1. Select Public static void main(Strings[ ] args).

      2. Deselect Constructors from superclass.

      3. Deselect Inherited abstract methods.

        Choose Finish.

        In Package Explorer, ExecuteReport.java appears in the ExecuteReport project.

    3. Open ExecuteReport.java in Java Editor, and add the required code. The ExecuteReport code is discussed later in this chapter.

    4. In Eclipse run-time workbench, compile the project by choosing Project →Build Project.

How to run the CSV report rendering extension

To run the CSV report rendering extension, using the ExecuteReport application, perform the following tasks:

  1. In Eclipse run-time workbench, right-click ExecuteReport, and choose Run As →Run from the menu. Run appears.

  2. On Run, perform the following tasks:

    1. In Java Application, select ExecuteReport, as shown in Figure 18-12.

      Selecting ExecuteReport

      Figure 18-12. Selecting ExecuteReport

    2. To change the working directory for the launch configuration, perform the following tasks:

      1. On Run, choose (x) = Arguments.

      2. In Working Directory, choose Other. Choose File System. Browse for Folder appears. Select the working directory that contains the ExecuteReports project for the launch configuration. Choose OK.

      3. On Run, choose Apply.

    3. To run the Java application using the launch configuration, choose Run.

How to view the CSV report rendering extension file output

  1. Navigate to the directory containing the CSV output file. This CSV report rendering extension example writes the CSV file to the following location:

    C:Program Fileseclipse
    untime-EclipseApplication
      ExecuteReport
    eports
  2. Using a text editor or other tool, open the file, and view its contents.

    Figure 18-13 shows the CSV output.

    CSV output

    Figure 18-13. CSV output

    The XML source code for the report design used in this example is discussed later in this chapter.

About ExecuteReport class

The ExecuteReport class runs a BIRT report and renders the output in CSV format, writing the text-based elements of the report to a file. The ExecuteReport class performs the following operations:

  • Configures the report engine

  • Sets the log configuration and logging level

  • Starts the platform and loads the plug-ins

  • Gets the report engine factory object from the platform and creates the report engine

  • Opens the report design

  • Creates a task to run and render the report

  • Set the rendering options, such as the output file and format

  • Runs the report and destroys the engine

  • Shuts down the engine

Listing 18-18 shows the code for the ExecuteReport class in the CSV report rendering extension example.

Example 18-18. The ExecuteReport class code

import java.util.logging.Level;
import org.eclipse.birt.core.framework.Platform;
import org.eclipse.birt.report.engine.api.EngineConfig;
import org.eclipse.birt.report.engine.api.CSVRenderOption;
import org.eclipse.birt.report.engine.api.IReportEngine;
import
   org.eclipse.birt.report.engine.api.IReportEngineFactory;
import org.eclipse.birt.report.engine.api.IReportRunnable;
import org.eclipse.birt.report.engine.api.IRunAndRenderTask;

public class ExecuteReport {

   static void executeReport( ) throws Exception
   {
      IReportEngine engine=null;
      EngineConfig config = null;
      config = new EngineConfig( );
      config.setEngineHome
         ( "C:/birt-runtime-2_1_0/ReportEngine" );
      config.setLogConfig( "c:/birt/logs", Level.FINE );
      Platform.startup( config );
      IReportEngineFactory factory =
         ( IReportEngineFactory ) Platform.createFactoryObject
         ( IReportEngineFactory
            .EXTENSION_REPORT_ENGINE_FACTORY );
      engine = factory.createReportEngine( config );
      engine.changeLogLevel( Level.WARNING );

      IReportRunnable design =
         engine.openReportDesign
            ( "reports/csvTest.rptdesign" );
      IRunAndRenderTask task =
         engine.createRunAndRenderTask( design );
      String format = CSVRenderOption.OUTPUT_FORMAT_CSV;
      if ( format.equals( CSVRenderOption.OUTPUT_FORMAT_CSV ))
      {
         CSVRenderOption csvOptions = new CSVRenderOption( );
         csvOptions.setOutputFormat( format );
         csvOptions.setOutputFileName( "reports/csvTest.csv" );
         task.setRenderOption( csvOptions );
      }

      task.run( );
      task.close( );
      engine.shutdown( );
      Platform.shutdown( );
      System.out.println("We are done!!!");
   }
   public static void main(String[] args) {
      try
      {
         executeReport( );
      }
      catch ( Exception e )
      {
         e.printStackTrace();
      }
   }
}

About the report design XML code

The XML file for the report design, csvTest.reportdesign, contains the following source code settings, as specified in the report design:

  • Data sources, including the ODA plug-in extension ID, driver class, URL, and user

  • Data sets, including the ODA JDBC plug-in extension ID, result set properties, and query text

  • Page setup, including the page footer

  • Body, containing the table structure and properties for the bound data columns, including the header, footer, and detail rows

The report design example specifies a data source that connects to org.eclipse.birt.report.data.oda.sampledb, the BIRT Classic Models sample database. Listing 18-19 shows the XML source code for the report design used to test the CSV rendering example. The sample application runs the report from the reports subfolder in the ExecuteReport project.

Example 18-19. The report design XML code

<?xml version="1.0" encoding="UTF-8"?>
<!-- Written by Eclipse BIRT 2.0 -->
<report xmlns="http://www.eclipse.org/birt/2005/design"
   version="3.2.2" id="1">
   <property name="createdBy">
      Eclipse BIRT Designer Version 1.0.1
      Build &lt;20050729-0746></property>
   <property name="units">in</property>
   <data-sources>
      <oda-data-source
         extensionID=
         "org.eclipse.birt.report.data.oda.sampledb"
         name="Data Source" id="2">
         <property
            name="odaDriverClass">
            org.eclipse.birt.report.data.oda.sampledb.Driver
         </property>
         <property
            name="odaURL">jdbc:classicmodels:sampledb
         </property>
         <property name="odaUser">ClassicModels</property>
      </oda-data-source>
   </data-sources>
   <data-sets>
      <oda-data-set
         extensionID=
            "org.eclipse.birt.report.data.oda.jdbc
               .JdbcSelectDataSet" name="Data Set" id="3">
            <structure name="cachedMetaData">
               <list-property name="resultSet">
                  <structure>
                     <property name="position">1</property>
                     <property name=
                        "name">PRODUCTNAME
                     </property>
                     <property
                        name="dataType">string
                     </property>
                  </structure>
                  <structure>
                     <property name="position">2</property>
                     <property
                        name="name">QUANTITYINSTOCK
                     </property>
                     <property
                        name="dataType">integer
                     </property>
                  </structure>
                  <structure>
                     <property name="position">3</property>
                     <property name="name">MSRP</property>
                     <property name="dataType">float</property>
                  </structure>
               </list-property>
            </structure>
            <property name="dataSource">Data Source</property>
            <property name="queryText">
               select CLASSICMODELS.PRODUCTS.PRODUCTNAME,
                       CLASSICMODELS.PRODUCTS.QUANTITYINSTOCK,
                       CLASSICMODELS.PRODUCTS.MSRP
               from CLASSICMODELS.PRODUCTS</property>
         </oda-data-set>
      </data-sets>
      <page-setup>
         <simple-master-page name="Simple MasterPage" id="4">
            <page-footer>
               <text id="5">
                  <property name="contentType">html</property>
                  <text-property name="content">
                     <![CDATA[<value-of>new Date()</value-of>]]>
                  </text-property>
               </text>
            </page-footer>
         </simple-master-page>
      </page-setup>
      <body>
         <table id="6">
            <property name="width">100%</property>
            <property name="dataSet">Data Set</property>
            <list-property name="boundDataColumns">
               <structure>
                  <property name="name">PRODUCTNAME</property>
                  <expression
                     name="expression">dataSetRow["PRODUCTNAME"]
                  </expression>
               </structure>
               <structure>
                  <property
                     name="name">QUANTITYINSTOCK
                  </property>
                  <expression
                     name="expression">
                     dataSetRow["QUANTITYINSTOCK"]
                 </expression>
              </structure>
              <structure>
                 <property name="name">MSRP</property>
                 <expression
                    name="expression">dataSetRow["MSRP"]
                 </expression>
              </structure>
           </list-property>
           <column id="28"/>
           <column id="29"/>
           <column id="30"/>
           <header>
              <row id="7">
                 <cell id="8">
                    <property name="colSpan">3</property>
                    <property name="rowSpan">1</property>
                    <property name="textAlign">center</property>
                       <label id="9">
                          <property
                             name="fontSize">x-large
                          </property>
                          <property
                             name="fontWeight">bold
                          </property>
                          <property
                             name="textAlign">center
                          </property>
                          <text-property
                             name="text">Report
                          </text-property>
                       </label>
                 </cell>
              </row>
              <row id="10">
                 <cell id="11">
                    <label id="12">
                       <text-property
                          name="text">PRODUCTNAME
                       </text-property>
                    </label>
                 </cell>
                 <cell id="13">
                    <label id="14">
                       <text-property
                          name="text">QUANTITYINSTOCK
                       </text-property>
                    </label>
                 </cell>
                 <cell id="15">
                    <label id="16">
                       <text-property
                          name="text">MSRP
                       </text-property>
                    </label>
                 </cell>
              </row>
           </header>
           <detail>
              <row id="17">
                 <cell id="18">
                    <data id="19">
                       <property
                          name="resultSetColumn">PRODUCTNAME
                       </property>
                    </data>
                 </cell>
                 <cell id="20">
                    <data id="21">
                    <property
                       name="resultSetColumn">QUANTITYINSTOCK
                    </property>
                 </data>
              </cell>
              <cell id="22">
                 <data id="23">
                    <property
                       name="resultSetColumn">MSRP
                    </property>
                 </data>
              </cell>
           </row>
        </detail>
        <footer>
           <row id="24">
              <cell id="25"/>
              <cell id="26"/>
              <cell id="27"/>
            </row>
         </footer>
      </table>
   </body>
</report>

BIRT Report Engine can render a report design for output using a standard emitter extension or a customized emitter extension, such as this CSV rendering example.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset