1. Reporting agents

Reporting agents in EDW are classes inherited from TEDWDBReport, which is itself inherited from TEDWDBAgent.

Note

TEDWReport is currently unused and reserved for future extension.

TEDWDBReport is a base class for all agents that take data from the DW and output it in some way. Reports are the application-level products of an EDW application. There may be many kinds of reports, including but not limited to: print-outs, HTML pages uploaded to a FTP server, PDF or OOo documents, text, XML or binary files.

1.1. Dataset reports (TEDWCDSReport and descendants)

TEDWCDSReport is a base class for reports that produce a dataset. Descendants specify the dataset structure and the way to get the data. This class is usually chained in an EDW program, with the produced dataset passed to some other agent that transforms it or otherwise manipulates it.

After executing the agent, reading the Output.DataSet configuration item will yield a reference to the generated dataset object, which is kept alive for the agent's lifetime. If you set the OutputDataSetFileName configuration item before executing the agent, then the output dataset will also be produced as an xml file. The xml format in this case is Delphi's ClientDataSet format. As you can easily imagine, this class uses an internal ClientDataSet to accumulate the data. It is not recommended for huge (meaning more than a few thousand rows) reports.

As we have said, you don't use a CDSReport as it is, but inherit from it. When you inherit, you should provide:

  • the dataset's structure (override BuildDataSetStructure and SetDataSetFieldProperties)

  • the data (override InternalFillDataSet)

  • optionally, any additional custom data you want to carry with the dataset (override SetDataSetOptionalParams)

  • optionally, any additional output configuration items you want to return to the calling program (override CollectOutputItems)

Please see the EDW reference for details about the methods mentioned above.

Once you have a dataset or the corresponding xml document on disk, you can process them. The following sections focus on processing the data as in-memory dataset or as generated xml files.

1.2. Processing datasets (TEDWDataSetReport and descendants)

You can process a dataset produced by the agent described above (or another agent) by means of an agent inherited from TEDWDataSetReport, like TEDWDataSetXMLReport. The former has an InputDataSet, an OutputFileName, can apply a DataMap to the input dataset's records and can exclude some input columns from the output (specify them in ExcludedFieldNames). Descendants override its abstract method InternalExportDataSet to export the data in a specific format. EDW will be adding more descendants in future releases; one of them is already available now, and it's the TEDWDataSetXMLReport.

The dataset xml report takes the input dataset and exports it as an xml file. used is simple: it is entirely tag-based, with a tag for each field value, and contains a <Header> tag with structure information (like display labels, field types and sizes, etc.). Here is a snippet:

<?xml version="1.0" encoding="utf-8"?>
<DataSet>
  <Header>
    <Field>
      <FieldName>ROW_TYPE</FieldName>
      <DisplayLabel>ROW_TYPE</DisplayLabel>
      <DataType>ftString</DataType>
      <Size>1</Size>
      <Visible>0</Visible>
    </Field>
    <Field>
      <FieldName>DESCRIPTION</FieldName>
      <DisplayLabel>Country Name</DisplayLabel>
      <DataType>ftString</DataType>
      <Visible>-1</Visible>
    </Field>
    <Field>
      <FieldName>D_20060523</FieldName>
      <DisplayLabel>23/05/2006</DisplayLabel>
      <DataType>ftInteger</DataType>
      <Visible>-1</Visible>
    </Field>
    ...
    <Field>
      <FieldName>TOTAL</FieldName>
      <DisplayLabel>Total</DisplayLabel>
      <DataType>ftInteger</DataType>
      <Visible>-1</Visible>
    </Field>
  </Header>
  <Record>
    <ROW_TYPE>0</ROW_TYPE>
    <DESCRIPTION>Italy</DESCRIPTION>
    <D_20060523>2</D_20060523>
    ...
    <TOTAL>6</TOTAL>
  </Record>
  ...
</DataSet>

1.3. Processing datasets with xslt

EDW allows you to integrate xslt technology into your reporting programs. The following sections introduce xslt and the support for it in EDW.

1.3.1. Introducing xslt

It is outside the scope of this section, or even this manual, to teach you the basics of xslt. We'll just say that it is an xml-based technology that allows you to take one or more input xml document and transform them into an output document, which can be xml, html, xhtml, or text. You can also use xsl-fo, a formatting xml-based language, to produce postscript or pdf files. Here is a list of resources for you to get more information:

Learning xslt is not very easy nor very fast, but it pays off in time. Xml-based languages and technologies are what the entire web is built upon, and you get to find excellent tools, resources and peer support just aboute everywhere. The list above is just a small fraction of what's available. We believe in the power and flexibility of these technologies and are going to push them more and more in EDW over the traditional report building techniques (which EDW supports as well, anyway).

1.3.2. Support for xslt in EDW

EDW features an agent that can process an xml file, produced by one of the agents described above, and transform it into an xml (in different format), html, xhtml, txt or pdf file. The agent uses an xslt stylesheet file called a template, and delegates the xslt processing to MSXML (it needs at least MSXML 2, which you'll find installed in any reasonably recent computer). This is the TEDWXSLAgent, which is documented in detail in the EDW reference. This agent calls Apache FOP to produce pdf files; in order to be able to do that you should:

  1. Install FOP in some folder (possibly a sub-folder of your application)

  2. Specify the FOP path (the path in which fop.bat is located) in the agent's FopPath configuration item

  3. Specify the name of an xsl-fo template (that is, an xsl stylesheet that produces a fo document) in the agent's InputXSLDocumentName configuration item

  4. Specify a file name with a .pdf extension in the agent's OutputDocumentName configuration item

The agent can also copy any additional support files (lik .js, .css, or image files) over to the output folder, and supports custom macros in the input xml document and text-based support files, and in the xslt template document.

If you need to transform an xml document on-the-fly, have a look at the TransformXMLText global routine (more details in the EDW reference). It's the routine used internally by the xsl agent.

1.3.3. Other xml-related utilities

There are several bits and pieces of code useful to work with xml in EDW and in the libraries it is based upon, like the CBLib. We suggest you browse the EDW reference and the source code for documentation on classes like TEDWSAXReader and TEDWXMLOutputStream.

1.4. CBLib-based document producers

EDW's architecture allows for integration of any reporting technology you might want to use. Writing the integration code is a delicate task that should be done once for all, and that we are willing to do for more products in the future; the document-production technology explained in this section is the one provided by Ethea's CBLib. This is the library upon which the InstantSolutions framework is based, and some parts of it are leveraged in EDW as well.

CBLib's document producers support several output formats with a consistent interface, which is wrapped in EDW by the TEDWCBReport class. This report has a couple of subobjects that help it doing its job: one is the dataset builder, which creates datasets upon which the report is based (you configure it through the agent's DataSetBuilder configuration slice); the other one is the doc producer, which takes the datasets and creates the actual report (you configure it through the agent's DocProducer configuration slice). The agent merely coordinates these two components. Let's take a closer look at them.

1.4.1. The dataset builder (TEDWDBDataSetBuilder)

This is a simple container for one or more SQL select statements that are used to build datasets. You can link datasets in master/detail relationships if needed. You configure the dataset builder through numbered configuration items: DataSet<X>.Name is the name you'll use to uniquely identify each dataset later; DataSet<X>.SQLStatement contains the dataset's SQL select statement; DataSet<X>.ParentDataSetName optionally points to the master dataset in a master/detail relationship.

You pass a database connection to the database builder upon construction, then you set any Configuration items and call the BuildAllDataSets method to have all datasets built and all data retrieved. When you use this class as a part of a CBReport, all this is done automatically and you just need to pass the configuration items in the appropriate slice.

1.4.2. The doc producer (TEDWCBDocProducer)

The built datasets are passed to the doc producer, that will load any needed external template or definition and create the final document. The following table summarizes the main configuration items of this object:

Table 7.1. TEDWCBDocProducer configuration items

Item nameData typeOptional/requiredPurpose
CBDocProducerClassNamestringrequiredDefines the type of report to build. TOOoWriterDocProducer uses OpenOffice.org Writer, TCBRBuilderDocProducer uses Report Builder, and TCBHtmlDocProducer produces html documents.
TemplateFileNamestringrequiredLocates the template to use to build the report. Its format depends on the type of producer: OOo Writer uses ott files, while Report Builder uses rtm files.
OutputFileNamestringrequiredName of the file that will be generated for the report. The extension can be used to force output in a particular format for classes that support more than one output format. The OOo and RB producers support both their respective native formats and the pdf format, while the html producer only supports the html format.
CreateTemplateOnlyBooleanoptional, default FalseIf True, instructs the report to automatically create a bare-bone template. In this case the report document is not generated, just the template is. Use this as a convenient way to create templates you can later modify.

You can also set a ReportTitle, a ReportSubTitle, and decide to show a preview on screen or not. This class is used by assigning a dataset builder to its DataSetBuilder propert, setting all needed Configuration items and call its ProduceDoc method. When you use this class as a part of a CBReport, all this is done automatically and you just need to pass the configuration items in the appropriate slice.

1.4.3. A CBReport example

The EDW demo contains examples of how to configure and use the CBReport agent. Here is a configuration file snippet that produces a very simple list report with OOo Writer and stores in PDF format:

// Include settings common to all programs.
{$include EDWDemo_inc.conf}
begin
  // Configure database access using constants included above.
  Configuration.SetString('DBFactoryId', EDWDemoDBFactoryId);
  Configuration.SetString('DBConnection.ConnectionString', EDWDemoDBConnectionString);

  // Configure the datasets that will be built for the report.
  // In this case it's a single dataset for a simple list.
  // Note that the main dataset should be called 'Main'.
  Configuration.SetString('DataSetBuilder.DataSet1.Name', 'Main');
  Configuration.SetString('DataSetBuilder.DataSet1.SQLStatement',
    'select ID, NAME, DESCRIPTION from COMPANY order by NAME');

  // Select the OpenOffice.org Writer document producer.
  Configuration.SetString('DocProducer.CBDocProducerClassName',
   'TOOoWriterDocProducer');

  // Create the report based on a given template. The template
  // should contain fields in <dataset name>.<field name> format.
  Configuration.SetString('DocProducer.TemplateFileName',
    'CompanyListReportOOoTemplate.ott');

  // Save the report in PDF format and under the given file name.
  // You can save in other formats, like ODT, as well.
  Configuration.SetString('DocProducer.OutputFileName',
    'CompanyListReportOOo.pdf');
    
  // Uncomment this line to disable the on-screen preview.
  //Configuration.SetBoolean('DocProducer.ShowReportPreview', False);
end.

Here is the code that you would use in an EDW program to load the above configuration file and produce the report:

A := Environment.AddAgent('CBReport');
A.Configuration.LoadFromFile('CompanyListReportOOo.conf');
A.Execute;